为表中的每一行创建一个UPDATE语句

时间:2019-06-25 07:07:11

标签: sql sql-server tsql sql-update

我想用另一台服务器上的表中的数据更新一台服务器上的表。这些表具有相同的列,我只想同步数据。我之前已经编写了一个脚本,可以为这些表创建插入语句(向SO提出问题并亲自回答...),但是创建UPDATE语句看似更简单的任务现在使我望而却步。也许是因为我刚从假期回来。

作为参考,这是我的“插入问题”:Creating "Not Exists"/Insert Into Statements - Stumped by nothing (NULL)

我正在尝试使用我的INSERT语句代码,但是我要么没有得到多行,要么只是得到了难以调试的错误消息(错误接近NULL)

所以,我想做的就是创建这样的语句,表中的每一行一个。

UPDATE WorkflowError 
   SET [ErrorDescription] = 'Error creating email' 
 WHERE [TargetSystem]='Fullmaktsnoden' 
   AND  [ErrorCode]='999' 
   AND  [ErrorText]='Error creating email' 
   AND [ErrorDescription] IS NULL

我可以使用一些通用指针,例如"Since you're now creating UPDATE statements instead of INSERT you need to think about..."

这是用于集成多个系统的表。我们“收集”从其他系统获得的消息,并将它们记录在ErrorDescription中。如果时间太长或具有误导性,我们在Errortext中放一个简短的说明,以显示给用户。 (在此示例中,我碰巧使用了相同的文本“错误创建电子邮件”,但在实际系统中,我们得到的错误描述要长得多)

一种尝试是这样的代码:

USE FullmaktsnodenProcess
GO

SET NOCOUNT ON

DECLARE @QUOTED_DATA VARCHAR(MAX),
        @DOES_EXIST VARCHAR(MAX),
        @SQL_KOD VARCHAR(MAX),
        @TABLE_NAME VARCHAR(MAX),
        @FIRST_COL INT,
        @LAST_COL INT,
        @THE_COLUMN VARCHAR(MAX)


/* INPUT DATA */
SELECT @TABLE_NAME = 'WorkflowError'
SELECT @FIRST_COL = 2 -- First column for Exists check
SELECT @LAST_COL = 4 -- Last column for Exists check
SELECT @THE_COLUMN = 'ErrorDescription'
/* */

SELECT @QUOTED_DATA=STUFF
(
    (
     SELECT ' ISNULL('''''''' + REPLACE('+COLUMN_NAME+','''''''','''''''''''') + '''''''','''+'NULL'''+''+')+'',''+'
     FROM information_schema.columns 
     WHERE table_name = @TABLE_NAME AND 
     COLUMN_NAME = @THE_COLUMN
     FOR XML PATH('')
    ),1,1,''
)

SELECT @QUOTED_DATA=SUBSTRING(@QUOTED_DATA,1,LEN(@QUOTED_DATA)-5)

SELECT @QUOTED_DATA

SELECT @DOES_EXIST=STUFF
(
    (
     SELECT ' ['+ COLUMN_NAME +']='' + ', 'ISNULL('''''''' + REPLACE('+COLUMN_NAME+','''''''','''''''''''') + '''''''','''+'NULL'''+''+')+'' AND '
     FROM information_schema.columns 
     WHERE table_name = @TABLE_NAME AND 
     ordinal_position BETWEEN @FIRST_COL AND @LAST_COL
     FOR XML PATH('')
    ),1,1,''
)

SELECT @DOES_EXIST


SELECT @SQL_KOD='SELECT ''UPDATE ' + @TABLE_NAME + ' SET ' +  QUOTENAME(@THE_COLUMN) + ' = ' + @QUOTED_DATA + ' WHERE ' + @DOES_EXIST + @THE_COLUMN + ' IS NULL'''

SELECT @SQL_KOD

EXECUTE (@SQL_KOD)

SET NOCOUNT OFF

GO

尝试执行@SQL_KOD会给出:“消息156,级别15,状态1,第3行,关键字'NULL'附近的语法不正确。”

从测试运行中,用EXECUTE(@SQL_KOD)注释掉:

@QUOTED_DATA = ISNULL('''' + REPLACE(ErrorDescription,'''','''''') + '''','NULL')

@DOES_EXIST = [TargetSystem]=' + ISNULL('''' + REPLACE(TargetSystem,'''','''''') + '''','NULL')+' AND  [ErrorCode]=' + ISNULL('''' + REPLACE(ErrorCode,'''','''''') + '''','NULL')+' AND  [ErrorText]=' + ISNULL('''' + REPLACE(ErrorText,'''','''''') + '''','NULL')+' AND 

@SQL_KOD = SELECT 'UPDATE WorkflowError SET [ErrorDescription] = ISNULL('''' + REPLACE(ErrorDescription,'''','''''') + '''','NULL') WHERE [TargetSystem]=' + ISNULL('''' + REPLACE(TargetSystem,'''','''''') + '''','NULL')+' AND  [ErrorCode]=' + ISNULL('''' + REPLACE(ErrorCode,'''','''''') + '''','NULL')+' AND  [ErrorText]=' + ISNULL('''' + REPLACE(ErrorText,'''','''''') + '''','NULL')+' AND ErrorDescription IS NULL'

1 个答案:

答案 0 :(得分:0)

这似乎符合要求。现在,数据中的引号已正确加倍,并且最终结果是表中每一行的一条UPDATE语句,这正是我想要的。正如我所提到的,当我在这里只处理一个已知列时,就不需要从information_schema.columns中读取内容,但是也许当我为另一个表修改此脚本时,情况并非如此……

USE FullmaktsnodenProcess
GO

SET NOCOUNT ON

DECLARE @QUOTED_DATA VARCHAR(MAX),
        @DOES_EXIST VARCHAR(MAX),
        @SQL_KOD VARCHAR(MAX),
        @TABLE_NAME VARCHAR(MAX),
        @FIRST_COL INT,
        @LAST_COL INT,
        @THE_COLUMN VARCHAR(MAX)


/* INPUT DATA */
SELECT @TABLE_NAME = 'WorkflowError'
SELECT @FIRST_COL = 2 -- First column for Exists check
SELECT @LAST_COL = 4 -- Last column for Exists check
SELECT @THE_COLUMN = 'ErrorDescription'
/* */

SELECT @QUOTED_DATA=STUFF
(
    (
     SELECT ' ISNULL(REPLACE('+QUOTENAME(COLUMN_NAME)+','''''''','''''''''''') + '''''''','''+'NULL'''+''+')+'',''+'
     FROM information_schema.columns 
     WHERE table_name = @TABLE_NAME AND 
     COLUMN_NAME = @THE_COLUMN
     FOR XML PATH('')
    ),1,1,''
)

SELECT @QUOTED_DATA=SUBSTRING(@QUOTED_DATA,1,LEN(@QUOTED_DATA)-5)

--SELECT @QUOTED_DATA

SELECT @DOES_EXIST=STUFF
(
    (
     SELECT ' '+ QUOTENAME(COLUMN_NAME) +'='''''' + ', 'ISNULL(REPLACE('+QUOTENAME(COLUMN_NAME)+','''''''','''''''''''') + '''''''','''+'NULL'''+''+')+'' AND '
     FROM information_schema.columns 
     WHERE table_name = @TABLE_NAME AND 
     ordinal_position BETWEEN @FIRST_COL AND @LAST_COL
     FOR XML PATH('')
    ),1,1,''
)

-- SELECT @DOES_EXIST

SELECT @SQL_KOD='SELECT ''UPDATE ' + @TABLE_NAME + ' SET ' +  QUOTENAME(@THE_COLUMN) + ' = ' + ''''''' + ' + @QUOTED_DATA + ' + ' + ''' WHERE ' + @DOES_EXIST + @THE_COLUMN + ' IS NULL ' + ''' Update_Script ' + 'FROM ' + @TABLE_NAME

-- SELECT @SQL_KOD

EXECUTE (@SQL_KOD)

SET NOCOUNT OFF

GO