Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如果列存在,则有条件地插入到表中_Sql Server_Tsql_Idempotent - Fatal编程技术网

Sql server 如果列存在,则有条件地插入到表中

Sql server 如果列存在,则有条件地插入到表中,sql-server,tsql,idempotent,Sql Server,Tsql,Idempotent,我正在尝试编写一个幂等元db迁移脚本,其中包括需要洗牌一些数据的脚本。在脚本的后面,我从中选择的一列被删除(迁移的目的是将数据从该列移动到一个新位置),因此我有如下内容(由EF Core生成): 然而,这并不像我希望的那样是幂等的;第二次运行脚本时,由于INSERT语句中出现错误,脚本失败,因为OldB列不再存在于bar上 但是,如果删除了OldB,则上面的guard子句将始终为false,因为在删除OldB的过程中,我们还将该行插入迁移历史记录中(是的,我已经检查过,现在也是这样;该行存在)。

我正在尝试编写一个幂等元db迁移脚本,其中包括需要洗牌一些数据的脚本。在脚本的后面,我从中选择的一列被删除(迁移的目的是将数据从该列移动到一个新位置),因此我有如下内容(由EF Core生成):

然而,这并不像我希望的那样是幂等的;第二次运行脚本时,由于
INSERT
语句中出现错误,脚本失败,因为
OldB
列不再存在于
bar

但是,如果删除了
OldB
,则上面的guard子句将始终为false,因为在删除
OldB
的过程中,我们还将该行插入迁移历史记录中(是的,我已经检查过,现在也是这样;该行存在)。因此,
INSERT
在没有它关心的所有列的情况下永远不会运行


如何编写像上面那样的幂等元
INSERT
,它在实际运行之前不会验证所有列的存在性?

您可以检查是否所有列都存在:

IF NOT EXISTS (SELECT * FROM [__EFMigrationsHistory] 
               WHERE [MigrationId] = N'AName')
BEGIN
     IF (SELECT COUNT(*) 
        FROM sys.columns 
        WHERE [object_id] = OBJECT_ID('Bars')
          AND name IN ('OldA', 'OldB')) = 2
     BEGIN
          EXEC('INSERT INTO Foos (A, B)
          SELECT OldA, OldB FROM Bars');
     END
END

-- a little later in the script:

IF NOT EXISTS (SELECT * FROM [__EFMigrationsHistory] 
               WHERE [MigrationId] = N'AnotherName')
BEGIN
      EXEC('ALTER TABLE [Bars] DROP COLUMN [OldB]');
END

您可以检查是否存在所有列:

IF NOT EXISTS (SELECT * FROM [__EFMigrationsHistory] 
               WHERE [MigrationId] = N'AName')
BEGIN
     IF (SELECT COUNT(*) 
        FROM sys.columns 
        WHERE [object_id] = OBJECT_ID('Bars')
          AND name IN ('OldA', 'OldB')) = 2
     BEGIN
          EXEC('INSERT INTO Foos (A, B)
          SELECT OldA, OldB FROM Bars');
     END
END

-- a little later in the script:

IF NOT EXISTS (SELECT * FROM [__EFMigrationsHistory] 
               WHERE [MigrationId] = N'AnotherName')
BEGIN
      EXEC('ALTER TABLE [Bars] DROP COLUMN [OldB]');
END

我打算建议使用动态SQL。我打算建议使用动态SQL。这仍然会产生相同的错误;似乎我在
INSERT
周围有一个保护子句来确保它永远不会被执行并不重要,它仍然被认为是无效的。例如,如果0=1,用
包装
插入
,仍然会产生错误。@TomasLycken请检查我的编辑。用动态SQL包装它将解决名称解析问题,检查将在运行时完成;似乎我在
INSERT
周围有一个保护子句来确保它永远不会被执行并不重要,它仍然被认为是无效的。例如,如果0=1,用
包装
插入
,仍然会产生错误。@TomasLycken请检查我的编辑。用动态SQL包装它将解决名称解析问题,检查将在运行时完成。