sql - TSQL:在 INSERT 之后运行 exec
问题描述
我需要从多个表中转换旧数据。我现在才发现,在为一个表编写存储过程之后,它还需要处理来自其他几个表的数据。这意味着需要更改我的程序以正确处理此问题。我想动态地做到这一点,同时远离性能影响。我了解了如何使用 exec sp_executesql @SQLStatement 来避免动态 SQL 的性能问题。
但是,如果我写以下内容,我不会得到任何结果:
SET @SQLStatement = 'select CONVERT(XML, ' + @ConvColumn + ') ' + @AdditionalColumns + ' from ' + @ConvTable
INSERT INTO @TempDataConv
exec sp_executesql @SQLStatement
然而,如果我写它明确定义表和列,这工作得很好:
INSERT INTO @TempDataConv
SELECT
DecPageID,
PolicyID,
PolicyNumber,
CONVERT(XML, DecInfo),
null
FROM [InternalPortal].[dbo].Decpages
可能会发生什么?由于没有返回任何结果,我不确定如何找出问题所在。我认为也许我无法做到以下几点。真的吗?我应该简单地将其写在不同表的 if 块中吗?
INSERT INTO @TempDataConv
exec sp_executesql @SQLStatement
解决方案
我怀疑如果您执行INSERT
内部动态语句,而不是使用INSERT INTO...EXEC...
. 这将导致这样的事情:
DECLARE @ConvColumn sysname,
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
DECLARE @AdditionalColumns table (Position int,ColumnName sysname);
SET @ConvColumn = N'DecInfo';
INSERT INTO @AdditionalColumns
VALUES(1,N'DecPageID'),
(2,N'PolicyID'),
(3,N'PolicyNumber');
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'INSERT INTO dbo.YourTable ({ColumnsList})' + @CRLF +
N'SELECT CONVERT(xml, ' + QUOTENAME(@ConvColumn) + N'),' + @CRLF +
STUFF((SELECT N',' + @CRLF +
N' ' + QUOTENAME(ColumnName)
FROM @AdditionalColumns
ORDER BY Position ASC
FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,3,N'') + @CRLF +
N'FROM [InternalPortal].[dbo].Decpages;';
--PRINT @SQL; --Your debugging best friend
EXEC sys.sp_executesql @SQL;
需要注意的是,您将无法使用表变量INSERT
进入,但是,您可以在动态语句的范围之外创建一个临时表并INSERT
进入该表。
另请注意,我通过使用QUOTENAME
. 这就是为什么我使用表变量来存储列名的原因,因为你永远无法使用分隔列表来实现这一点(这真的会让注入门大开)。您还需要替换{ColumnsList}
为要插入的实际列。
推荐阅读
- javascript - 使用 javascript 从网站获取文本
- python - 在 tf.keras 中使用 softmax 作为顺序层和使用 softmax 作为密集层的激活函数有什么区别?
- gem5 - 我可以在 gem5 中更精细地调试吗?
- python - 在 google colab 中使用 datagen.flow_from_directory 并没有提高训练和验证的准确性
- android - Flutter:为 ImagePicker 使用 Listview.builder
- angular - 如何将 ionic 中的 ccavenue 支付网关与 Angular 集成
- html - 如何隔离标签及其内容
- python - 估计文本文件中值的函数
- jquery - 使用 Asp.net Core MVC Bootstrap 4,对于服务器端添加的模型状态错误,我无法让不显眼的验证正常工作
- linux - 如何使用 cURL 发布请求将文件内容作为数据原始有效负载中的字符串发送