【问题标题】:How can I perform a MERGE in DbFit?如何在 DbFit 中执行 MERGE?
【发布时间】:2016-12-01 23:23:39
【问题描述】:

我想确保在对数据库执行测试之前填充参考表。我要使用的特定数据可能已经在测试数据库中,也可能不在测试数据库中,所以我想执行 MERGE(也称为 UPSERT),如果数据还没有在表中,它会插入数据并更新如果是的话。

从我在谷歌上看到的,DbFit 似乎不支持 MERGE 命令,也不支持执行从外部 SQL 脚本文件加载的 SQL(计划 B 是在 SQL 脚本文件中创建 MERGE,然后加载文件并在 DbFit 中运行它)。

是否有任何直接的方式在 DbFit 中执行 MERGE,或者我需要创建一个特殊的夹具类来执行它?

【问题讨论】:

    标签: .net fitnesse dbfit


    【解决方案1】:

    我想出了如何使用 FitSharp 版本的 DbFit 中的标准命令来做到这一点。

    此示例针对 SQL Server 数据库执行。 Oracle 的 MERGE 语句有类似的语法,虽然我不知道它如何处理临时表。 MySQL 没有 MERGE 语句;它有一个非标准的命令来实现同样的事情。它也支持临时表,但我不熟悉 MySql 临时表的语法。

    这是我想要将数据合并到的目标表的定义:

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

    这是将数据合并到其中的 DbFit Flow 模式页面:

    !| 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不需要最后的Query命令,添加它只是为了检查目标表是否已正确更新。

    请注意,插入命令必须为临时表使用由三部分组成的名称,至少在 SQL Server 中是这样。当对 SQL Server 执行 Insert 命令时,它会在后台查询 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 数据库中查找它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多