我收到此错误: 必须声明标量变量“@ TempTable1”。 如果我从@ Temptable1周围删除单引号但没有返回任何行,则查询有效。
ALTER PROCEDURE dbo.StoredProcedure2
@Studentcode int
AS
DECLARE @sql AS nvarchar(max)
DECLARE @pivot_list AS nvarchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS nvarchar(max) -- Leave NULL for COALESCE technique
Declare @TempTable1 AS table(CourseTitel nvarchar(50) , Grade nvarchar(50))
INSERT INTO @TempTable1 (CourseTitel, Grade)
SELECT Courses.CourseTitel, Status.Status
FROM Status
INNER JOIN Courses ON Status.CourseCode = Courses.CourseCode
WHERE (Status.StudentCode = @Studentcode)
SELECT @pivot_list = COALESCE(@pivot_list + ', ','') + '[' + CONVERT(varchar, PIVOT_CODE) + ']',
@select_list = COALESCE(@select_list + ', ','') + '[' + CONVERT(varchar, PIVOT_CODE) + '] AS [col_' + CONVERT(varchar, PIVOT_CODE) + ']'
FROM (SELECT DISTINCT PIVOT_CODE
FROM (SELECT CourseTitel, Grade, ROW_NUMBER() OVER (PARTITION BY CourseTitel ORDER BY Grade) AS PIVOT_CODE
FROM @TempTable1)
AS rows)
AS PIVOT_CODES
SET @sql = ';WITH p AS (SELECT CourseTitel, Grade,
ROW_NUMBER() OVER (PARTITION BY urseTitel ORDER BY Grade) AS PIVOT_CODE
FROM ' + @TempTable1 + ' ) SELECT CourseTitel, ' + select_list + '
FROM p PIVOT (MIN(Grade)FOR PIVOT_CODE IN (' + @pivot_list + ')) AS pvt'
--PRINT (@sql)
EXEC (@sql)
/* SET NOCOUNT ON */
答案 0 :(得分:1)
因此,您要声明一个表变量,并尝试对其运行动态SQL。问题是使用exec
或sp_executeSql
完成的动态SQL基本上在其自己的作用域中运行,因此表变量不会在那里声明,并且随后不能在查询中使用。
我可以提出两种解决方法:
使表格可用作临时表格。由于临时表是真实表,因此可以在任何范围内访问它们,因此可以在动态sql中访问它们。一些伪tsql会像:
...
if object_id('tempdb..#TempTable1 ') is not null
drop table #TempTable1
create table #TempTable1 (CourseTitel nvarchar(50) , Grade nvarchar(50))
...
@sql = '... AS PIVOT_CODE FROM #TempTable1) SELECT CourseTitel...'
将表变量作为参数表格传递给动态sql块。这只适用于sql server 2008及更高版本。但是,这需要将表的结构定义为sql server类型。这可以在系统级别执行一次,例如:
CREATE TYPE TempTableType AS TABLE (CourseTitel nvarchar(50) , Grade nvarchar(50))
然后我们可以使用该类型声明表变量,并将其作为参数传递给动态sql
...
declare @TempTable1 AS TempTableType
...
@sql = N'... AS PIVOT_CODE FROM @TempTable1) SELECT CourseTitel...'
EXEC sp_executesql @SQL,
N'@TempTable1 TempTableType READONLY',
@TempTable1 =@TempTable1