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

Sql server 使用数据表和表名作为参数创建表的存储过程,sql-server,stored-procedures,Sql Server,Stored Procedures,我正在尝试创建一个存储过程,该过程将接受DataTable和Table name作为参数,并创建一个表。程序如下: ALTER PROCEDURE [dbo].[SPROC_IMPORT_UPLOADED_EXCEL_DATA] @DataTbl emTable READONLY , @TableName [varchar](50) AS BEGIN DECLARE @SQL nvarchar(MAX) ------------------------------------

我正在尝试创建一个存储过程,该过程将接受DataTable和Table name作为参数,并创建一个表。程序如下:

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;
但是,将显示相同的错误。有什么建议吗

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存储过程\u导入\u上载\u EXCEL\u数据@DataTbl=…,@TableName=…

更新:

如果需要解析表变量,请声明
@table table(col,type…
,或创建用户定义函数来返回表结果

尝试执行此过程时:使用
exec存储过程\u导入\u上载\u EXCEL\u数据@DataTbl=…,@TableName=…

更新:


如果需要解析表变量,请声明
@table table(col,type…
,或者创建用户定义函数来返回表结果

此处遇到的问题是由于变量范围造成的。您的表值参数超出了动态sql中的范围。但是,如果您使用临时表,您可以绕过这个问题,因为临时表仍然在动态sql的作用域中

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


您在这里遇到的问题是由于变量作用域引起的。您的表值参数超出了动态sql中的范围。但是,如果您使用临时表,您可以绕过这个问题,因为临时表仍然在动态sql的作用域中

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


为什么使用
EXEC sp\u executesql@SQL
而不是
EXEC(@SQL)
?@LONG我更喜欢使用sp\u executesql,因为它允许参数。当然,在这种情况下,不能使用参数。:)检查我的答案@H.Bandi,我根据您使用的SPI EXEC(@SQL)进行了修改。它给出了相同的错误。为什么使用
EXEC sp\u executesql@SQL
而不是
EXEC(@SQL)
?@LONG我更喜欢使用sp\u executesql,因为它允许参数。当然,在这种情况下,不能使用参数。:)检查我的答案@H.Bandi,我根据您使用的SPI EXEC(@SQL)进行了修改。它给出了相同的错误。我非常确定@DataTbl是一个表值参数而不是字符串值。无论@DataTbl的类型是什么,基于
SELECT*FROM+@DataTbl
,它应该是一个varcharRight。但它们传递的是表值参数,而不是字符串。因此,虽然这是一个关于如何使用varchar执行此操作的极好示例,但它对OP不起作用。老实说,OP是一个有缺陷的概念。因此我感到困惑,我非常确定@DataTbl是一个表值参数而不是字符串值。无论@DataTbl类型是什么,都基于
SELECT*FROM+@DataTbl
,这应该是一个很好的选择。但它们传递的是表值参数,而不是字符串。因此,虽然这是一个关于如何使用varchar执行此操作的极好示例,但它对OP不起作用。老实说,OP是一个有缺陷的概念。因此我对xD感到困惑
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