[SQL][問題處理]利用 View 來解決 bulk insert 時,克服DB欄位與csv檔中欄位不對等的問題

[SQL][問題處理]利用 View 來解決 bulk insert 時,克服DB欄位與csv檔中欄位不對等的問題

早上在 Super SQL Server 的 FB 社群中看到一個蠻好玩的問題,有朋友在詢問 "請問當使用bulk insert塞資料時,有辦法克服DB欄位與csv檔中欄位不對等的問題嗎?",其實這個問題當使用 BCP 或者是 Bulk Insert 都會遇到,因為他們都需要一對一的欄位。而以往看到很多的朋友在處理的時候,有的人就捨棄不使用,有的人是自己利用寫程式去處理,這裡我提供一個自己常用的方式,利用 View 來騙過去。

 

首先我先建立一個範例用的 Items 表格

SET NOCOUNT ON
IF OBJECT_ID('Items') IS NOT NULL DROP TABLE Items
  
DECLARE @Items TABLE
( Item_Id varchar(10), Item_Name varchar(10), Sales_Qty numeric(10) )
  
DECLARE @Ptr INT, @RecordCount INT
SET @Ptr = 0
SET @RecordCount = 5000    -- 範例表的筆數
 
-- 亂數產生資料  
WHILE @Ptr < @RecordCount    
BEGIN
   SET @Ptr += 1 
   INSERT INTO @Items    VALUES ( RIGHT('000000000'+LTRIM(STR(@Ptr)),10 ), RIGHT(newid(),10 ) , ROUND( RAND()*100,1 ) )
END
  
-- 產生測試表格 Items
SELECT * INTO Items FROM @Items  

 

此時我們可以先用指令將資料匯出成為 BCP 檔案

bcp Source.dbo.Items in Items.bcp -T -n

image

 

此時我們利用 TRUNCATE TABLE 的指令刪除表格內的資料,並且調整一下 Items 的欄位,增加兩個測試的欄位在當中,這兩個增加的欄位我們故意不放在最後面,這樣比較能貼近我們的真實狀況。

image

 

再利用 BCP 的指令匯回剛剛產生的資料,果然會發生錯誤的訊息 ( 預設的最大錯誤數是 10 )

image

 

此時我們利用 CREATE VIEW 的指令來建立一個用來做匯入的對應表格

CREATE VIEW [dbo].[Mock_Items]
AS
    SELECT Item_Id,Item_Name,Sales_Qty
    FROM Items

 

此時我們調整一下匯入的指令,改成匯入到 Mock_Items 這個 View,再測試一次,果然如我們預期的將資料給匯入成功了。

image

 

查看一下資料真的如我們原始資料一樣,沒有對應的欄位這個時候欄位就會是 NULL,但如果不想要 NULL 的話,則可以調整欄位的 DEFAULT 值

image

 

這裡我們將欄位 XXX 預設值設定為 0 , 欄位 YYY 預設是今天的日期。

ALTER TABLE dbo.Items ADD CONSTRAINT DF_Items_XXX DEFAULT (0) FOR XXX
GO
ALTER TABLE dbo.Items ADD CONSTRAINT DF_Items_YYY DEFAULT (getdate()) FOR YYY
GO

 

接下來我們再將 Items 這個資料表給清空,再重新匯入一次,此時每個欄位就會有值了

image

 

同樣的方式,要是我們的資料來源是 CSV 檔案,則也可以用同樣的方式

BULK INSERT Mock_Items  FROM 'D:\Sample.csv' 
WITH
     (
        FIELDTERMINATOR =','
      )

 

這樣也是可以成功的瞞天過海,把資料按照我們想要的方式給匯入了。