[英]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.