SQL 服务器:使用一个动态查询、常量等将值插入 Table
SQL Server : Insert Values into a Table with one Dynamic Query, constants, etc
我有以下查询,将一些值插入到一个 table 中,这是有效的:
INSERT INTO Table(id, field_1, field_2, field_3, field_4)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , 'ddMMyyyy') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, '0'
FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition
这工作正常。当我想在 table 中插入一个新值并且这个值是从动态查询中获得时,问题就来了:
这是单独工作的查询(定义了变量)
EXEC ('SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table]')
如果我想将它包含在插入查询中,但我认为这是不可能的。至少它不是为我编译的:
INSERT INTO Table(id, field_1, field_2, field_3, field_4, **field_5**)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , 'ddMMyyyy') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, '0', **EXEC ('SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table]')**
FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition
也许有更好的解决方案将此动态查询包含在插入子句中?
编辑:在 Nisarg 评论和支持后我修改了查询:
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'',
SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table] from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')
似乎唯一的问题是在 SELECT 子句中:
Incorrect syntax near the keyword 'SELECT'.
我还删除了以下其中一项:from kat.[dbo].[Imported_Table] FROM kat.[dbo].[Imported_Table]
。写了两次。
您可以使用 INSERT EXEC。您必须在动态查询内外声明 table 的变量。
在动态查询结束时,只需从 table 变量 select 并将结果集插入外部 table 变量
DECLARE @table SomeTable ( ID INT )
DECLARE @query NVARCHAR(120) = 'declare @table SomeTable (id int)
insert into @table values(1),(2)
select * from @table '
INSERT INTO @table
EXEC(@query)
SELECT * FROM @table
您不能只在查询中间编写动态查询。但是您可以将整个查询转换为动态查询:
EXEC( 'INSERT INTO Table(id, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, ''0'',
SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table] FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition')
不过请先PRINT
进行检查,以确保查询没有任何语法错误。
此外,您应该避免使用 EXEC
。相反,您可以使用 sp_executesql
,它可以更好地防止动态查询的 SQL 注入。
更新
我之前没有将 SELECT
子查询括在方括号中。它应该是这样的。请注意下面第 7 行中的 (SELECT TOP 1 '+@ColumnName+' from kat.[dbo].[Imported_Table]) as field_5
语句:
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'',
(SELECT TOP 1 '+@ColumnName+' from kat.[dbo].[Imported_Table]) as field_5
from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')
或者,由于您使用的是动态查询,因此以下内容也应该有效。我已经删除了子查询,并在查询中附加了字段名称。
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'', '+@ColumnName+'
from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')
我有以下查询,将一些值插入到一个 table 中,这是有效的:
INSERT INTO Table(id, field_1, field_2, field_3, field_4)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , 'ddMMyyyy') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, '0'
FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition
这工作正常。当我想在 table 中插入一个新值并且这个值是从动态查询中获得时,问题就来了:
这是单独工作的查询(定义了变量)
EXEC ('SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table]')
如果我想将它包含在插入查询中,但我认为这是不可能的。至少它不是为我编译的:
INSERT INTO Table(id, field_1, field_2, field_3, field_4, **field_5**)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , 'ddMMyyyy') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, '0', **EXEC ('SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table]')**
FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition
也许有更好的解决方案将此动态查询包含在插入子句中?
编辑:在 Nisarg 评论和支持后我修改了查询:
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'',
SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table] from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')
似乎唯一的问题是在 SELECT 子句中:
Incorrect syntax near the keyword 'SELECT'.
我还删除了以下其中一项:from kat.[dbo].[Imported_Table] FROM kat.[dbo].[Imported_Table]
。写了两次。
您可以使用 INSERT EXEC。您必须在动态查询内外声明 table 的变量。 在动态查询结束时,只需从 table 变量 select 并将结果集插入外部 table 变量
DECLARE @table SomeTable ( ID INT )
DECLARE @query NVARCHAR(120) = 'declare @table SomeTable (id int)
insert into @table values(1),(2)
select * from @table '
INSERT INTO @table
EXEC(@query)
SELECT * FROM @table
您不能只在查询中间编写动态查询。但是您可以将整个查询转换为动态查询:
EXEC( 'INSERT INTO Table(id, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +@MAINFIELD+@FIELDTYPE), @MAINFIELD, date , @ColumnName, ''0'',
SELECT '+@ColumnName+' from kat.[dbo].[Imported_Table] FROM kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = @TABLENAME and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = @CurrentPosition')
不过请先PRINT
进行检查,以确保查询没有任何语法错误。
此外,您应该避免使用 EXEC
。相反,您可以使用 sp_executesql
,它可以更好地防止动态查询的 SQL 注入。
更新
我之前没有将 SELECT
子查询括在方括号中。它应该是这样的。请注意下面第 7 行中的 (SELECT TOP 1 '+@ColumnName+' from kat.[dbo].[Imported_Table]) as field_5
语句:
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'',
(SELECT TOP 1 '+@ColumnName+' from kat.[dbo].[Imported_Table]) as field_5
from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')
或者,由于您使用的是动态查询,因此以下内容也应该有效。我已经删除了子查询,并在查询中附加了字段名称。
set @MAINFIELD= CAST(@MAINCURRENCY AS VARCHAR);
set @FIELDTYPE= CAST(@RATETYPE AS VARCHAR);
SET @ColumnName = CAST(@ColumnName AS VARCHAR)
SET @CurrentPosition = CAST(@CurrentPosition AS INT)
EXEC( 'INSERT INTO Devisen_geldkurs(devisen_geldkurs, field_1, field_2, field_3, field_4, field_5)
SELECT (SELECT INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME + FORMAT(convert (datetime,date) , ''ddMMyyyy'') +''@MAINFIELD''+''@FIELDTYPE''), "@MAINFIELD", date , "@ColumnName", ''0'', '+@ColumnName+'
from kat.[dbo].[Imported_Table]
INNER JOIN INFORMATION_SCHEMA.COLUMNS on INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = "Imported_Table" and INFORMATION_SCHEMA.COLUMNS.ORDINAL_POSITION = ''@CurrentPosition''')