我想用另一台服务器上的表中的数据更新一台服务器上的表。这些表具有相同的列,我只想同步数据。我之前已经编写了一个脚本,可以为这些表创建插入语句(向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'
答案 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