sql - 创建“不存在”/插入语句 - 无所事事(NULL)
问题描述
我需要一个脚本来生成插入语句,但检查数据是否不存在,这是因为它应该定期在并行系统上运行,其中不同的数据将被添加到系统中,但我们希望它们的表是同步的。我有基本的 ide 和借用的部分代码,但遇到语法错误,我无法解决。
我的代码基于 Param Yadav 在将选择结果转换为插入脚本 - SQL Server中显示的代码,但我需要检查表中已有的数据。(我需要稍后添加更多的“花里胡哨,但要逐步进行)
我自己的主要补充是 @NOT_EXISTS 部分,它应该在 NOT EXISTS 检查的 WHERE 子句中。如果我用普通的 WHERE 0=1 替换它,我不会收到语法错误,因此它表明错误在我的 @NOT_EXISTS 字符串中。
编辑:昨天我以为我自己的问题有了答案,但是在“真实数据”上运行时,我发现有些行对于 QUOTENAME 来说太长了,我必须“手动”修复这些引号(脚本中的连接)。 .
SET NOCOUNT ON
DECLARE @CSV_COLUMN VARCHAR(MAX),
@QUOTED_DATA VARCHAR(MAX),
@NOT_EXISTS VARCHAR(MAX),
@SQL_KOD VARCHAR(MAX),
@TABLE_NAME VARCHAR(MAX),
@FILTER_CONDITION VARCHAR(MAX)='',
@FIRST_COL INT,
@LAST_COL INT
/* INPUT DATA */
SELECT @TABLE_NAME = 'WorkflowError'
SELECT @FIRST_COL = 2
SELECT @LAST_COL = 4
/* */
SELECT @CSV_COLUMN=STUFF
(
(
SELECT ',['+ NAME +']' FROM sys.all_columns
WHERE OBJECT_ID=OBJECT_ID(@TABLE_NAME) AND
is_identity!=1 FOR XML PATH('')
),1,1,''
)
--SELECT @CSV_COLUMN
SELECT @QUOTED_DATA=STUFF
(
(
SELECT ' ISNULL(QUOTENAME('+NAME+','+QUOTENAME('''','''''')+'),'+'''NULL'''+')+'','''+'+' FROM sys.all_columns
WHERE OBJECT_ID=OBJECT_ID(@TABLE_NAME) AND
is_identity!=1 FOR XML PATH('')
),1,1,''
)
SELECT @QUOTED_DATA=SUBSTRING(@QUOTED_DATA,1,LEN(@QUOTED_DATA)-5)
SELECT @QUOTED_DATA
SELECT @NOT_EXISTS=STUFF
(
(
SELECT ' ['+ COLUMN_NAME +']=', 'ISNULL(QUOTENAME('+COLUMN_NAME+','+QUOTENAME('''','''''')+'),'+'''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 @NOT_EXISTS=SUBSTRING(@NOT_EXISTS,1,LEN(@NOT_EXISTS)-4)
SELECT @NOT_EXISTS
--SELECT @NOT_EXISTS=' 0=1 '
SELECT @SQL_KOD='SELECT ''
IF NOT EXISTS(SELECT 1
FROM ' + @TABLE_NAME + ' WHERE ' + @NOT_EXISTS + ')
BEGIN
INSERT INTO '+@TABLE_NAME+'('+@CSV_COLUMN+')
VALUES('''+'+'+@QUOTED_DATA+'+'+''')
END
GO '''+' Insert_Scripts
FROM '+@TABLE_NAME + @FILTER_CONDITION
SELECT @SQL_KOD
EXECUTE (@SQL_KOD)
GO
[stackoverflow won't let me post code unless it's formatted, but then the strings below won't be as they are created in the script...]
When I do SELECT @NOT_EXISTS=' 0=1 ' I get an INSERT line for each row in my table:
IF NOT EXISTS(SELECT 1 FROM WorkflowError WHERE 0=1 )
BEGIN
INSERT INTO WorkflowError([TargetSystem],[ErrorCode],[ErrorText],[RetryMaxCount],[RetryStrategyName],[ErrorDescription])
VALUES('EttLiv','800','Value cannot be null. Parameter name: source','0',NULL,'Value cannot be null. Parameter name: source')
END
GO
With my @NOT_EXISTS code the @SQL_KOD string becomes this:
SELECT 'IF NOT EXISTS(SELECT 1 FROM WorkflowError
WHERE [TargetSystem]=ISNULL(QUOTENAME(TargetSystem,''''),'NULL'))
BEGIN
INSERT INTO WorkflowError([TargetSystem],[ErrorCode],[ErrorText],[RetryMaxCount],[RetryStrategyName],[ErrorDescription])
VALUES('+ISNULL(QUOTENAME(TargetSystem,''''),'NULL')+','
+ ISNULL(QUOTENAME(ErrorCode,''''),'NULL')+','
+ ISNULL(QUOTENAME(ErrorText,''''),'NULL')+','
+ ISNULL(QUOTENAME(RetryMaxCount,''''),'NULL')+','
+ ISNULL(QUOTENAME(RetryStrategyName,''''),'NULL')+','
+ ISNULL(QUOTENAME(ErrorDescription,''''),'NULL')+')
END
GO ' Insert_Scripts FROM WorkflowError
However, trying to execute that @SQL_KOD line just gives:
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'NULL'.
...and I can't find out where I have done wrong, if it's in my thinking or if it's just a misplaced quotation mark...
解决方案
您希望@SQL_KOD 从哪里获取其值?因为如果您从插入语句之外的某个地方检索 TargetSystem / ErrorCode / ... / ErrorDescription 的值,我会期待一个“来自”语句。如果要输入变量,则缺少变量的定义和变量名前面的@-符号。
至于保持引号满意:尝试使用 QUOTED_IDENTIFIER OFF 编写代码 - 您可以通过在双引号 (") 之间写入来创建整个 @SQL_KOD 变量,并且单引号的行为类似于普通引号。
对您的代码进行非常基本的重写可能如下所示:
SET QUOTED_IDENTIFIER OFF
DECLARE @SQL_KOD VARCHAR(MAX)
SET @SQL_KOD =
"DECLARE @WorkFlowError TABLE ([TargetSystem] NVARCHAR(200),[ErrorCode] NVARCHAR(200))
IF NOT EXISTS ( SELECT 1 FROM @WorkFlowError )
BEGIN
INSERT INTO @WorkFlowError ([TargetSystem],[ErrorCode])
SELECT ISNULL(QUOTENAME([TargetSystem],''''),'NULL')
, ISNULL(QUOTENAME([ErrorCode],''''),'NULL')
FROM (
SELECT [TargetSystem]='Foo'
, [ErrorCode]='Bar'
) src
END";
推荐阅读
- sql - SSIS:我需要从 For Each 循环中的 2 个不同查询填充 2 个 Excel 电子表格
- javascript - 使用带有类的 setInterval() 交换图像 – p5.js
- java - 在处理中增加 textSize
- hibernate - Netbeans为什么显示空白?
- javascript - IOS Voiceover 不读取 div 内容
- ms-access - 根据组合框内容在 MS Access 表单中选择记录
- tmux - Tmux 条件颜色设置
- javascript - 如何添加默认泛型类型 - 使用 Flow 输入 createReducer
- c# - 在DataGrid中折叠列时获取单元格值
- groovy - JUnit Assume.assumeNotNull 抛出空指针而不是跳过测试