这不是关于使用表变量-而是关于在动态SQL游标中使用局部变量来携带db地址,理论上它的工作原理如下:-假设已经声明了全局变量@sql、AnalysisLocation和@sp_executeSql。
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
'+@JoinFilter+'
WHERE pfc.pfc_status = 0
AND year(mtx.pfc_dateofservice) = '+cast(@Year as nvarchar)+'
'+@Criteria+'
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这在编译动态代码时不会产生语法错误,但是在调用此过程时:Msg1087,Level 15,State 2,第27行必须声明表变量"@ServerAndDB_for_pfcAppended“。
当我使用这种类型的结构从过程外部将location变量作为全局变量传入时,它会正确地接受它,但是作为一个局部变量,它似乎默认假定它是一个表变量。
我不想创建表变量。这是一个不可能的结构吗?
发布于 2011-09-11 07:26:12
该错误是由于您试图使用参数化的表名造成的。这是不可能的,只要表名应该是一个参数,就会使用动态查询,基本上就像这样:
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
'+@JoinFilter+'
WHERE pfc.pfc_status = 0
AND year(mtx.pfc_dateofservice) = '+cast(@Year as nvarchar)+'
'+@Criteria+'
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_sethttps://stackoverflow.com/questions/7338846
复制相似问题