动态 T-SQL 存储过程插入不同的表

Dynamic T-SQL stored procedure to insert in differents tables

实现此目标的最佳方法是什么

INSERT INTO @TableName (@ColumnNames)
    EXEC sp_executesql @SQLResult;

其中 @TableName@ColumnNames@SQLResultvarchar 个变量

我试图避免为每个 table.

做一个单独的插入

最好的方法是为所有 table 编写(或生成)所有需要的程序。与所谓的 "generic solution" 相比,可以自动生成的 23 tables 乘以 4 个过程(插入、更新、删除和 select)在开发时间和痛苦上算不了什么。

这是导致性能不佳、代码不可读、sql 注入危险和无数调试时间的途径。

首先,非常感谢您提出的所有意见。我同意 SQL 动态调试起来很痛苦(感谢上帝,管理工作室有这种可能性)。而且,当然还有数百种不同的解决方案

我终于用这种方法解决了,或多或少我试图解释为什么这种SQL动态的解决方案。客户使用 xlsx 电子表格输入某些数据,所以我阅读电子表格并插入(数据取决于电子表格插入到正确的 table)。稍后 table 中的数据导出到 XML 以发送第三方软件。

SET @SEL = N'';
DECLARE sel_cursor CURSOR
FOR (SELECT  sc.name as field
      FROM sys.objects so INNER JOIN sys.columns sc ON so.[object_id]=sc.[object_id]
      WHERE so.name= @TableName and sc.name not in ('InitDate', 'EndDate', 'Version', 'Status'));

SET @SEL = ''; set @i = 0;
OPEN sel_cursor
FETCH NEXT FROM sel_cursor INTO @field
WHILE @@FETCH_STATUS = 0
BEGIN
    set @sel = @sel + ', '+ @field 
    set @i   = 1;
    FETCH NEXT FROM sel_cursor INTO @field
END
CLOSE sel_cursor;
DEALLOCATE sel_cursor;


SET @SQL = N''
SET @SQL = @SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET @SQL = @SQL + N'('
SET @SQL = @SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET @SQL = @SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET @SQL = @SQL + N'Database='+@file +''''+ ','
SET @SQL = @SQL + N'''select * from ['+ @SheetName + '$]'''+');'

EXEC sp_executesql @SQL

SET @SQL = N'';
SET @SQL = @SQL + N'
SELECT '+''''+CAST(@initDate AS VARCHAR(10))+'''' +', '+ ''''+CAST(@endDate AS VARCHAR(10))+'''' 
      + ', '+ CAST(@version AS VARCHAR(2)) +', ' +''''+@status+''''
      + @SEL 
 +'    FROM DBO.XLImport '


DECLARE cols_cursor CURSOR
   FOR (Select COLUMN_NAME From INFORMATION_SCHEMA.COLUMNS where table_name = @tableName);
SET @SEL = ''; set @i = 0;
OPEN cols_cursor
FETCH NEXT FROM cols_cursor INTO @field
WHILE @@FETCH_STATUS = 0
BEGIN
   set @sel = @sel + @field + ', '
   set @i   = 1;
   FETCH NEXT FROM cols_cursor INTO @field
END
CLOSE cols_cursor;
DEALLOCATE cols_cursor;

SET @SEL = LEFT(@SEL, LEN(@SEL) - 1) -- remove last ,


SET @SQL = N''
SET @SQL = @SQL + N'SELECT * INTO XLImport FROM OPENROWSET'
SET @SQL = @SQL + N'('
SET @SQL = @SQL + N'''Microsoft.ACE.OLEDB.12.0'''+','
SET @SQL = @SQL + N'''Excel 12.0 Xml; HDR=YES;'
SET @SQL = @SQL + N'Database='+@file +''''+ ','
SET @SQL = @SQL + N'''select * from ['+ @SheetName + '$]'''+');'

EXEC sp_executesql @SQL

SET @SQLString =
N'INSERT INTO '+ @TableName + '('+ @SEL +') ' + @SQL;

EXEC sp_executesql @SQLString

使用EXECUTE sp_executesql @sql,示例如下:

create proc sp_DynamicExcuteStore 
@TableName varchar(50),
@ColumnNames varchar(50),
@SQLResult varchar(max)
as
declare @sql nvarchar(max) = '
INSERT INTO '+@TableName+' ('+@ColumnNames+')
    EXEC sp_executesql '+@SQLResult
EXECUTE sp_executesql @sql
go
create proc sp_test
as
select 'test' + convert(varchar,RAND())
go
CREATE TABLE [dbo].[Test](
    [text1] [nvarchar](500) NULL
) ON [PRIMARY]

GO
DECLARE @return_value int

EXEC    @return_value = [dbo].[sp_DynamicExcuteStore]
        @TableName = N'Test',
        @ColumnNames = N'text1',
        @SQLResult = N'proc_test'

SELECT  'Return Value' = @return_value

GO

SELECT TOP 1000 [text1]
  FROM [test].[dbo].[Test]