【问题标题】:Create an UPDATE statement for every row in a table为表中的每一行创建一个 UPDATE 语句
【发布时间】:2019-06-25 07:07:11
【问题描述】:

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

【问题讨论】:

  • 评论不用于扩展讨论;这个对话是moved to chat
  • 下一步:此代码创建所需的最终结果,现在只需创建创建此代码的代码...: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 ' Update_Script FROM WorkflowError

标签: sql sql-server tsql sql-update


【解决方案1】:

这似乎符合要求。数据中的引号现在正确加倍,最终结果是表中每一行的一个 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2013-08-05
    • 1970-01-01
    • 2018-12-17
    • 2021-12-25
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多