Как я могу выполнить MERGE в DbFit?

Я хотел бы убедиться, что справочные таблицы заполнены перед выполнением тестов с базой данных. Конкретные данные, которые я хочу использовать, могут быть или не быть уже в тестовой базе данных, поэтому я хотел бы выполнить MERGE (также известную как UPSERT), которая вставит данные, если они еще не были в таблице, и обновите это если есть было.

Из того, что я вижу из Google, DbFit, похоже, не поддерживает команду MERGE, а также не поддерживает выполнение SQL, загруженного из внешнего файла сценария SQL (план Б состоял в том, чтобы создать MERGE в файле сценария SQL, а затем загрузить файл и запустите его в DbFit).

Есть ли простой способ выполнить MERGE в DbFit, или для этого мне нужно будет создать специальный класс приспособлений?


person Simon Tewsi    schedule 01.12.2016    source источник


Ответы (1)


Я понял, как это сделать, используя только стандартные команды версии DbFit от FitSharp.

Этот пример выполняется для базы данных 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. Команда Query в конце не нужна для MERGE, она была добавлена ​​только для проверки правильности обновления целевой таблицы.

Обратите внимание, что команда Insert должна использовать имя из трех частей для временной таблицы, по крайней мере, в SQL Server. Когда команда Insert выполняется для 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 будет возвращать идентификатор объекта временной таблицы только в том случае, если имя таблицы указано как имя, состоящее из трех частей. Это связано с тем, что SQL Server всегда создает временные таблицы в базе данных tempdb, а не в той базе данных, где эта временная таблица будет использоваться. Функция OBJECT_ID не найдет метаданные для временной таблицы, пока ей не будет указано искать их в базе данных tempdb.

person Simon Tewsi    schedule 11.12.2016