2016-12-01 32 views
0

我想確保在對數據庫執行測試之前填充參考表。我想要使​​用的具體數據可能已經或可能不在測試數據庫中,所以我想要執行一個MERGE(也稱爲UPSERT),如果數據尚未存在於表中並將其更新它如果是。如何在DbFit中執行MERGE?

從我可以從谷歌搜索中看到,DbFit似乎不支持MERGE命令,也不支持從外部SQL腳本文件加載執行的SQL(計劃B是在SQL腳本文件中創建MERGE ,然後加載文件並在DbFit中運行它)。

在DbFit中是否有任何直接進行MERGE的方法,還是我需要創建一個特殊的夾具類來完成它?

回答

0

我想出瞭如何使用FitSharp的DbFit版本的標準命令。

本示例針對的是SQL Server數據庫。 Oracle對MERGE語句的語法類似,儘管我不知道它是如何處理臨時表的。 MySQL沒有MERGE語句;它有一個非標準的命令可以達到同樣的效果。它也支持臨時表,但我不熟悉MySql臨時表的語法。

這是我想要的數據合併到一個目標表的定義:

CREATE TABLE Student 
(
    [Name] NVARCHAR(200), 
    DateOfBirth DATETIME, 
    Notes NVARCHAR(1000) 
); 

這裏的DbFit流模式頁,將數據合併到它:

!| Execute | CREATE TABLE #MergeSource ([Name] NVARCHAR(200), DateOfBirth DATETIME, Notes NVARCHAR(1000)); | 

!| Insert | tempdb.dbo.#MergeSource | 
| Name  | DateOfBirth | Notes    | 
| Jane Smith | 1997-09-24 | These are some notes | 
| John Doe | 2000-04-06 | Other notes   | 

!| Execute | !- 
MERGE INTO Student AS target 
USING 
    (
     SELECT [Name], [DateOfBirth], [Notes] 
     FROM #MergeSource 
    ) AS source 
ON target.[Name] = source.[Name] 
WHEN MATCHED THEN 
    UPDATE 
    SET [DateOfBirth] = source.[DateOfBirth], 
     [Notes] = source.[Notes] 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT ([Name], [DateOfBirth], [Notes]) 
    VALUES (source.[Name], source.[DateOfBirth], source.[Notes]); 
    -! | 

!| Query | SELECT [Name], DateOfBirth, Notes FROM Student; | 
| Name  | DateOfBirth | Notes    | 
| Jane Smith | 1997-09-24 | These are some notes | 
| John Doe | 2000-04-06 | Other notes   | 

首先一個臨時表被創建爲充當MERGE的數據源。要合併的數據被插入到臨時表中,然後執行MERGE語句。 MERGE不需要查詢命令,只需添加查詢命令即可檢查目標表是否已正確更新。

注意Insert命令必須使用三部分名稱作爲臨時表,至少在SQL Server中。當針對SQL Server,幕後它將查詢SYS.COLUMNS獲取有關表列執行信息插入命令插入到:

exec sp_executesql N'select c.[name], TYPE_NAME(c.system_type_id) as [Type], c.max_length, 
    0 As is_output, 0 As is_cursor_ref, c.precision, c.scale 
    from tempdb. sys.columns c 
    where c.object_id = OBJECT_ID(@objname) 
    order by column_id', 
     N'@objname nvarchar(23)', 
     @objname=N'tempdb.dbo.#MergeSource' 

OBJECT_ID函數將只返回一個臨時表,如果對象ID表名稱被指定爲三部分名稱。這是因爲SQL Server始終在tempdb數據庫中創建臨時表,而不是臨時表將要使用的數據庫。 OBJECT_ID函數不會查找臨時表的元數據,除非它被告知在tempdb數據庫中查找它。