我正在尝试将TABLE变量传递给sp_executesql过程:
DECLARE @params NVARCHAR(MAX)
SET @params = '@workingData TABLE ( col1 VARCHAR(20),
col2 VARCHAR(50) )'
EXEC sp_executesql @sql, @params, @workingData
我收到错误:
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'TABLE'.
我尝试在'TABLE'之后省略列规范。我还尝试将表声明为动态SQL中的变量。但没有运气......
在我看来,TABLE变量不允许在此过程中作为参数传递?顺便说一句:我正在运行MSSQL2008 R2。
我对使用像#workingData这样的本地临时表不感兴趣,因为我从另一个过程加载了工作数据:
INSERT INTO @workingData
EXEC myProc @param1, @param2
我不能直接进入温度变通(对吧?)......
任何帮助表示赞赏!
答案 0 :(得分:12)
如果您使用的是SQL Server 2008,要将表变量传递给存储过程,您必须先定义表类型,例如:
CREATE TYPE SalesHistoryTableType AS TABLE
(
[Product] [varchar](10) NULL,
[SaleDate] [datetime] NULL,
[SalePrice] [money] NULL
)
GO
或使用存储在数据库中的现有表类型。
使用此查询查找现有的表类型
SELECT * FROM sys.table_types
要在存储过程中使用,请将输入变量声明为表:
CREATE PROCEDURE usp_myproc
(
@TableVariable SalesHistoryTableType READONLY
)
AS BEGIN
--Do stuff
END
GO
在传递给存储过程之前填充表变量:
DECLARE @DataTable AS SalesHistoryTableType
INSERT INTO @DataTable
SELECT * FROM (Some data)
调用存储过程:
EXECUTE usp_myproc
@TableVariable = @DataTable
进一步讨论here。
答案 1 :(得分:3)
好的,这会让我得到我想要的东西,但肯定不是很漂亮:
DECLARE @workingData TABLE ( col1 VARCHAR(20),
col2 VARCHAR(20) )
INSERT INTO @workingData
EXEC myProc
/* Unfortunately table variables are outside scope
for the dynamic SQL later run. We copy the
table to a temp table.
The table variable is needed to extract data directly
from the strored procedure call above...
*/
SELECT *
INTO #workingData
FROM @workingData
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT * FROM #workingData'
EXEC sp_executesql @sql
必须有更好的方法将此临时结果集传递给sp_executesql!?
此致 亚历
答案 2 :(得分:2)
虽然这可能无法直接回答您的问题,但它应该可以解决您的问题。
您确实可以将存储过程执行的结果捕获到临时表中:
INSERT INTO #workingData
EXEC myProc
因此,请将代码更改为如下所示:
CREATE TABLE #workingData ( col1 VARCHAR(20),
col2 VARCHAR(20) )
INSERT INTO #workingData
EXEC myProc
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT * FROM #workingData'
EXEC sp_executesql @sql
此致 添
答案 3 :(得分:0)
Alter PROCEDURE sp_table_getcount
@tblname nvarchar(50) ,
@totalrow int output
AS
BEGIN
Declare @params nvarchar(1000)
Declare @sql nvarchar(1000)
set @sql = N'Select @cnt= count(*) From @tbl'
set @params = N'@tbl nvarchar(50) , @cnt int OUTPUT'
Exec sp_executesql @sql , @params ,@tbl=@tblname , @cnt = @totalrow OUTPUT
END
GO
请注意,上面的代码不能用作表格,因为对象超出了范围。它会给你错误:必须声明表变量。为了解决这个问题,我们可以做到以下几点。
Alter PROCEDURE sp_table_getcount
@tblname nvarchar(50) ,
@totalrow int output
AS
BEGIN
Declare @params nvarchar(1000)
Declare @sql nvarchar(1000)
set @sql = N'Select @cnt= count(*) From dbo.' + @tblname
set @params = N'@cnt int OUTPUT'
Exec sp_executesql @sql , @params , @cnt = @totalrow OUTPUT
END
GO
答案 4 :(得分:0)
所谓的TableType
很棘手。 @Alex版本应该可以使用。但是,为了简化和提高性能,请检查sys.tables
是否匹配表名,同时又不影响安全性和性能。
在这里
create proc [dbo].Test11
@t1 AS nvarchar(250), @t2 nvarchar(250)
AS
BEGIN
SET nocount ON;
DECLARE @query AS nvarchar(MAX)
if exists (select * from sys.tables where name = @t1) and
exists (select * from sys.tables where name = @t2)
begin
SET @query = N'select * FROM '+ @t1 + N' join ' + @t2 + N' ON ...' ;
select 'Safe and fast'
print @query
exec sp_executesql @query
end
else
select 'Bad, no way Jose.'
SET nocount OFF;
END
GO