2011-09-07 97 views
0

這不是關於使用表變量 - 這是關於使用本地變量在動態SQL遊標中攜帶數據庫地址,理論上它的工作原理如下: - 假定全局變量@sql,AnalysisLocation和@sp_executeSql已被宣佈。動態SQL將局部變量作爲表變量讀取?

ALTER PROCEDURE [dbo].[sp_AggregateCompliance_Report] 
@clientID int, 
@InvScrDBLocation nvarchar(250), 
@JoinFilter nvarchar(max) = '', 
@Criteria nvarchar(max) = '', 
@Year int = NULL 

as 

declare @sql nvarchar(4000) 


set @sql = ' 
IF EXISTS (SELECT * FROM sys.tables WHERE name = ''tmp_Aggregate_Compliance_counts'') 
TRUNCATE TABLE tmp_Aggregate_Compliance_counts 
ELSE 
CREATE TABLE tmp_Aggregate_Compliance_counts (
pfc_fk_prv_pkid int, 
RxYear int, 
RxMonth int, 
Compliance decimal (6,5)) 
' print @sql EXEC sp_executesql @sql 


SET @Criteria = isnull(case when @Criteria like 'WHERE %' then 'AND '+substring(@criteria,7,len(@criteria)-6) else @Criteria end ,'') 
SET @Year = isnull(@year, year(getdate())-1) 


set @sql = ' 
DECLARE @fk_cli_pkid INT 
    , @ServerAndDB_for_pfcAppended nvarchar(100) 

DECLARE client_set CURSOR FOR 
SELECT DISTINCT mtx.fk_cli_pkid, SettingValue+ ''.dbo.pfc_appended'' 
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx 
JOIN prola7.Invoice_Screens.dbo.client_definition AS def 
ON  mtx.fk_cli_pkID = def.fk_cli_pkid 
AND  fk_lkSettings_pkID = 45 
AND  RecordStatus = 1 

OPEN client_set 

FETCH next FROM client_set 
INTO @fk_cli_pkid, @ServerAndDB_for_pfcAppended 

WHILE @@FETCH_STATUS = 0 BEGIN 

INSERT INTO tmp_Aggregate_Compliance_counts (pfc_fk_prv_pkid, RxYear, RxMonth, Compliance) 

SELECT pfc.pfc_fk_prv_pkid 
    , year(mtx.pfc_dateofservice) AS RxYear 
    , 0 AS RxMonth 
    , cast(mtx.Compliance as decimal (6,5)) 
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx 
LEFT OUTER JOIN @ServerAndDB_for_pfcAppended AS pfc 
ON  mtx.pp_clientfile = pfc.pp_clientfile 
AND  mtx.pp_mirror_pkid = pfc.pp_mirror_pkid 
AND  mtx.fk_cli_pkid  = @fk_cli_pkid 
'[email protected]+' 
WHERE pfc.pfc_status = 0 
AND  year(mtx.pfc_dateofservice) = '+cast(@Year as nvarchar)+' 
'[email protected]+' 
GROUP BY pfc.pfc_fk_prv_pkid, year(mtx.pfc_dateofservice) 


FETCH next FROM client_set 
INTO @fk_cli_pkid, @ServerAndDB_for_pfcAppended 

END 

CLOSE client_set 
DEALLOCATE client_set 
' print @sql EXEC sp_executesql @sql 

這編譯動態代碼時不產生語法錯誤,調用這個程序然而,當:消息1087,級別15,狀態2,行27 必須聲明表變量「@ServerAndDB_for_pfcAppended」。

當我使用這種類型的結構將位置變量作爲一個全局變量從程序外部傳遞給它時,它正確地接受它,但是作爲局部變量,它似乎默認假設我打算它是一個表變量。

我不想創建表變量。這是不可能的結構嗎?

+0

你得到了什麼確切的錯誤信息?如果您提供可運行的代碼來演示此問題,這也會很有幫助。 –

+0

生成的實際腳本和錯誤可以通過上面的編輯... –

回答

1

該錯誤是由於您試圖擁有參數化表名稱所致。這是不可能的,每當一個表名應該是一個參數,動態查詢中使用,基本上是這樣的:

SET @sql = 'SELECT … FROM ' + @tablename + ' WHERE …' 

我想,在你的情況光標應該取出的動態查詢,除了對於使用參數化表名的部分。像這樣的東西應該可能做到:

ALTER PROCEDURE [dbo].[sp_AggregateCompliance_Report] 
@clientID int, 
@InvScrDBLocation nvarchar(250), 
@JoinFilter nvarchar(max) = '', 
@Criteria nvarchar(max) = '', 
@Year int = NULL 

as 

declare @sql nvarchar(4000) 


set @sql = ' 
IF EXISTS (SELECT * FROM sys.tables WHERE name = ''tmp_Aggregate_Compliance_counts'') 
TRUNCATE TABLE tmp_Aggregate_Compliance_counts 
ELSE 
CREATE TABLE tmp_Aggregate_Compliance_counts (
pfc_fk_prv_pkid int, 
RxYear int, 
RxMonth int, 
Compliance decimal (6,5)) 
' print @sql EXEC sp_executesql @sql 


SET @Criteria = isnull(case when @Criteria like 'WHERE %' then 'AND '+substring(@criteria,7,len(@criteria)-6) else @Criteria end ,'') 
SET @Year = isnull(@year, year(getdate())-1) 


DECLARE @fk_cli_pkid INT 
    , @ServerAndDB_for_pfcAppended nvarchar(100) 

DECLARE client_set CURSOR FOR 
SELECT DISTINCT mtx.fk_cli_pkid, SettingValue+ ''.dbo.pfc_appended'' 
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx 
JOIN prola7.Invoice_Screens.dbo.client_definition AS def 
ON  mtx.fk_cli_pkID = def.fk_cli_pkid 
AND  fk_lkSettings_pkID = 45 
AND  RecordStatus = 1 

OPEN client_set 

FETCH next FROM client_set 
INTO @fk_cli_pkid, @ServerAndDB_for_pfcAppended 

WHILE @@FETCH_STATUS = 0 BEGIN 

set @sql = ' 
INSERT INTO tmp_Aggregate_Compliance_counts (pfc_fk_prv_pkid, RxYear, RxMonth, Compliance) 

SELECT pfc.pfc_fk_prv_pkid 
    , year(mtx.pfc_dateofservice) AS RxYear 
    , 0 AS RxMonth 
    , cast(mtx.Compliance as decimal (6,5)) 
FROM mtx_ComplianceAndEarlyRefill_tracking AS mtx 
LEFT OUTER JOIN @ServerAndDB_for_pfcAppended AS pfc 
ON  mtx.pp_clientfile = pfc.pp_clientfile 
AND  mtx.pp_mirror_pkid = pfc.pp_mirror_pkid 
AND  mtx.fk_cli_pkid  = @fk_cli_pkid 
'[email protected]+' 
WHERE pfc.pfc_status = 0 
AND  year(mtx.pfc_dateofservice) = '+cast(@Year as nvarchar)+' 
'[email protected]+' 
GROUP BY pfc.pfc_fk_prv_pkid, year(mtx.pfc_dateofservice) 
' print @sql EXEC sp_executesql @sql 


FETCH next FROM client_set 
INTO @fk_cli_pkid, @ServerAndDB_for_pfcAppended 

END 

CLOSE client_set 
DEALLOCATE client_set 
+0

這證實了我的懷疑。感謝您的答覆。 –