[英]SQL Server: issue with declaring variable in dynamic SQL
我创建了一个动态存储过程,其开始如下。
我可以保存它而不会出错,但是在执行它时似乎无法识别@temp变量,因为它会引发以下错误:“必须声明表变量“ @temp”。“
这可能是因为错误的引号/转义,如果是的话,我该如何更改它才能使其正确(我对SQL还是很陌生,所以某些引号可能是错误的或丢失的)?
我的SP(第一部分):
@selection nvarchar(100)
AS
BEGIN
SET NOCOUNT ON;
BEGIN
DECLARE @temp AS TABLE
(
ranking int,
item nvarchar(100),
groupCount int,
groupName nvarchar(100)
)
DECLARE @sql nvarchar(max)
SET @sql = '
INSERT INTO @temp
(
ranking,
item,
groupCount,
groupName
)
SELECT RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
' + @selection + ',
COUNT(*) AS groupCount,
''currentMonth'' AS groupName
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + ''01'', 112)
GROUP BY ' + @selection + '
ORDER BY groupCount desc, ' + @selection + '
...
迈克,在此先感谢您的帮助。
正如我在评论部分中已经提到的那样,Dynamic Sql有自己的作用域,在该作用域之外声明的任何变量对于动态sql都是不可见的,您必须在动态sql内部声明该变量。 如下所示。
SET @sql = N' DECLARE @temp AS TABLE
(
ranking int,
item nvarchar(100),
groupCount int,
groupName nvarchar(100)
)
INSERT INTO @temp
(
ranking,
item,
groupCount,
groupName
)
SELECT RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
' + @selection + ',
COUNT(*) AS groupCount,
''currentMonth'' AS groupName
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + ''01'', 112)
GROUP BY ' + @selection + '
ORDER BY groupCount desc, ' + @selection + '
希望你做得很好,好吧,我认为您可能会重新考虑使用变量表,因为当执行EXEC(@sql)时,SQL无法理解@temp变量的含义,因此我建议使用临时表而不是变量表,这是新代码:
BEGIN
SET NOCOUNT ON;
BEGIN
if object_id('temp') is not null
drop table temp
create table temp
(
ranking int,
item nvarchar(100),
groupCount int,
groupName nvarchar(100)
)
DECLARE @sql nvarchar(max)
SET @sql = '
INSERT INTO temp
(
ranking,
item,
groupCount,
groupName
)
SELECT RANK() OVER(ORDER BY COUNT(*) desc, policy) [Rank],
' + @selection + ',
COUNT(*) AS groupCount,
''currentMonth'' AS groupName
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + ''01'', 112)
GROUP BY ' + @selection + '
ORDER BY groupCount desc, ' + @selection + '
...
if object_id('temp') is not null
drop table temp
希望thiw能帮到你
当您执行EXEC或sp_executesql时,将为进程空间获得另一个名称空间(作用域)。 从表变量更改为本地临时表#temp。
以下是使用sp_who2的快速示例,说明了本地临时表的使用。
诚挚
Ĵ
代码段
-- CREATE LOCAL TABLE
CREATE TABLE #WHO2
(
[spid] int not null
, [status] varchar (255) not null
, [login] varchar (255) not null
, [host_name] varchar (255) not null
, [blk_by] varchar(10) not null
, [db_name] varchar (255) null
, [command] varchar (255) not null
, [cpu_time] int not null
, [disk_io] int not null
, [last_batch] varchar (255) not null
, [program_name] varchar (255) null
, [spid2] int not null
, [request_id] int not null
); ;
-- DYNAMIC SQL
DECLARE @VAR_TSQL VARCHAR(MAX);
SET @VAR_TSQL = 'INSERT #WHO2 EXEC sp_who2';
EXECUTE (@VAR_TSQL);
GO
-- TABLE PERSISTS UNTIL SPID (CONNECTION) IS BROKEN
SELECT * FROM #WHO2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.