在对数据库执行测试之前,我希望确保填充了引用表。我想要使用的特定数据可能已经存在,也可能没有在测试数据库中,因此我想要执行一个合并(也称为UPSERT),如果数据不在表中,它将插入数据,如果是,则更新它。
从Googling中可以看出,DbFit似乎不支持MERGE命令,也不支持执行从外部SQL脚本文件加载的SQL (计划B是在script文件中创建合并,然后加载该文件并在DbFit中运行)。
在DbFit中是否有任何直接执行合并的方法,或者我是否需要创建一个特殊的夹具类来完成它?
发布于 2016-12-11 11:23:40
我想出了如何使用FitSharp版本的DbFit中的标准命令来完成这个任务。
此示例是针对 Server数据库执行的。Oracle的合并语句有类似的语法,不过我不知道它是如何处理临时表的。MySQL没有合并语句;它有一个非标准的命令来实现相同的功能。它还支持临时表,但我不熟悉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 |首先,创建一个临时表作为合并的数据源。要合并的数据插入临时表,然后执行合并语句。合并不需要末尾的查询命令,只为检查目标表是否已正确更新而添加。
注意,Insert命令必须为临时表使用三个部分的名称,至少在Server中是这样。当对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。这是因为Server总是在tempdb数据库中创建临时表,而不是使用临时表的数据库。除非告诉OBJECT_ID函数查找temp表的tempdb数据库,否则它不会找到临时表的元数据。
https://stackoverflow.com/questions/40922231
复制相似问题