如何在 DbFit 中执行 MERGE?
How can I perform a MERGE in DbFit?
我想确保在对数据库执行测试之前填充引用 table。我想使用的特定数据可能已经在也可能不在测试数据库中,所以我想执行 MERGE(也称为 UPSERT),如果数据不在 table 并更新它(如果是)。
从我在谷歌上看到的,DbFit 似乎不支持 MERGE 命令,也不支持执行从外部 SQL 脚本文件加载的 SQL(计划 B 是在 SQL 脚本文件中创建 MERGE,然后加载文件并 运行 在 DbFit 中)。
在 DbFit 中是否有直接执行 MERGE 的方法,或者我是否需要创建一个特殊的夹具 class 来执行此操作?
我想出了如何使用 FitSharp 版本的 DbFit 中的标准命令来完成它。
此示例针对 SQL Server 数据库执行。 Oracle 的 MERGE 语句有类似的语法,尽管我不知道它如何处理临时 tables。 MySQL 没有 MERGE 语句;它有一个非标准的命令来实现同样的事情。它还支持临时 tables 但我不熟悉 MySql 临时 tables.
的语法
这是目标的定义table我想将数据合并到:
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 |
首先创建一个临时的 table 作为 MERGE 的数据源。将要合并的数据插入到临时 table 中,然后执行 MERGE 语句。 MERGE 不需要末尾的查询命令,添加它只是为了检查目标 table 是否已正确更新。
请注意,插入命令必须使用由三部分组成的临时名称 table,至少在 SQL 服务器中是这样。当针对 SQL 服务器执行插入命令时,它会在后台查询 sys.columns 以获取有关要插入的 table 的列信息:
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'
如果 table 名称指定为三部分名称,OBJECT_ID 函数将仅 return 临时 table 的对象 ID。这是因为 SQL 服务器总是在 tempdb 数据库中创建 temp tables,而不是在将要使用 temp table 的数据库中。 OBJECT_ID 函数不会找到 temp table 的元数据,除非它被告知在 tempdb 数据库中查找它。
我想确保在对数据库执行测试之前填充引用 table。我想使用的特定数据可能已经在也可能不在测试数据库中,所以我想执行 MERGE(也称为 UPSERT),如果数据不在 table 并更新它(如果是)。
从我在谷歌上看到的,DbFit 似乎不支持 MERGE 命令,也不支持执行从外部 SQL 脚本文件加载的 SQL(计划 B 是在 SQL 脚本文件中创建 MERGE,然后加载文件并 运行 在 DbFit 中)。
在 DbFit 中是否有直接执行 MERGE 的方法,或者我是否需要创建一个特殊的夹具 class 来执行此操作?
我想出了如何使用 FitSharp 版本的 DbFit 中的标准命令来完成它。
此示例针对 SQL Server 数据库执行。 Oracle 的 MERGE 语句有类似的语法,尽管我不知道它如何处理临时 tables。 MySQL 没有 MERGE 语句;它有一个非标准的命令来实现同样的事情。它还支持临时 tables 但我不熟悉 MySql 临时 tables.
的语法这是目标的定义table我想将数据合并到:
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 |
首先创建一个临时的 table 作为 MERGE 的数据源。将要合并的数据插入到临时 table 中,然后执行 MERGE 语句。 MERGE 不需要末尾的查询命令,添加它只是为了检查目标 table 是否已正确更新。
请注意,插入命令必须使用由三部分组成的临时名称 table,至少在 SQL 服务器中是这样。当针对 SQL 服务器执行插入命令时,它会在后台查询 sys.columns 以获取有关要插入的 table 的列信息:
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'
如果 table 名称指定为三部分名称,OBJECT_ID 函数将仅 return 临时 table 的对象 ID。这是因为 SQL 服务器总是在 tempdb 数据库中创建 temp tables,而不是在将要使用 temp table 的数据库中。 OBJECT_ID 函数不会找到 temp table 的元数据,除非它被告知在 tempdb 数据库中查找它。