使用数据表和表名作为参数创建表的存储过程

时间:2017-01-04 21:01:53

标签: sql-server stored-procedures

我尝试创建一个存储过程,接受DataTable和Table名称作为参数并创建一个表。这是程序:

ALTER PROCEDURE [dbo].[SPROC_IMPORT_UPLOADED_EXCEL_DATA]
    @DataTbl emTable READONLY ,
    @TableName [varchar](50)
AS
BEGIN

DECLARE @SQL nvarchar(MAX)

-------------------------------------------------------------------------------
--Check 1: Checking if the table is already present
-------------------------------------------------------------------------------     

IF OBJECT_ID (@TableName,'U') IS NOT NULL
        SET @SQL = N'INSERT INTO ' + @TableName + ' SELECT * FROM ' + @DataTbl
    ELSE
        SET @SQL = N'SELECT * INTO ' + @TableName + ' FROM ' + @DataTbl

EXEC sp_executesql @SQL
END

显示以下错误:

Msg 137, Level 16, State 1, Procedure SPROC_IMPORT_UPLOADED_EXCEL_DATA, Line 8 [Batch Start Line 7]
Must declare the scalar variable "@DataTbl".

在研究错误后,尝试通过将参数添加到sp_executesql来修改过程。

EXEC sp_executesql @SQL,
    N'@DataTbl emTable READONLY' ,
    '@TableName [varchar](50)',
    @DataTbl,
    @TableName;

但是,会显示相同的错误。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

ALTER PROCEDURE [dbo].[SPROC_IMPORT_UPLOADED_EXCEL_DATA]
    @DataTbl [varchar](50) ,
    @TableName [varchar](50)
AS
BEGIN

DECLARE @SQL nvarchar(MAX)

-------------------------------------------------------------------------------
--Check 1: Checking if the table is already present
-------------------------------------------------------------------------------     

IF OBJECT_ID (@TableName,'U') IS NOT NULL
        SET @SQL = N'INSERT INTO ' + @TableName + ' SELECT * FROM ' + @DataTbl
    ELSE
        SET @SQL = N'SELECT * INTO ' + @TableName + ' FROM ' + @DataTbl

EXEC (@SQL)
END

当您尝试执行此过程时:使用EXEC SPROC_IMPORT_UPLOADED_EXCEL_DATA @DataTbl = ..., @TableName=...

更新:

如果您需要解析表变量,请声明@Table Table(col, type...)或创建用户定义函数以返回表格结果

答案 1 :(得分:0)

您遇到的问题是由于范围可变。您的表值参数超出了动态sql的范围。但是,如果使用临时表,则可以解决此问题,因为临时表仍将在动态sql的范围内。

这样的事可以让你接近。注意使用QUOTENAME。这将极大地帮助最小化sql注入的风险。我建议将@TableName的数据类型更改为sysname而不是varchar(50)。

ALTER PROCEDURE [dbo].[SPROC_IMPORT_UPLOADED_EXCEL_DATA]
@DataTbl emTable READONLY ,
@TableName [varchar](50)
AS
BEGIN

select *
into #TempData
from @DataTbl

DECLARE @SQL nvarchar(MAX)

-------------------------------------------------------------------------------
--Check 1: Checking if the table is already present
-------------------------------------------------------------------------------     

IF OBJECT_ID (@TableName,'U') IS NOT NULL
    SET @SQL = N'INSERT INTO ' + QUOTENAME(@TableName) + ' SELECT * FROM #TempData'
ELSE
    SET @SQL = N'SELECT * INTO ' + QUOTENAME(@TableName) + ' FROM #TempData'

EXEC sp_executesql @SQL
END