我创建了一个脚本来根据数据动态创建表,并将数据插入到这些表中。该脚本包含对链接服务器查询的调用,因为源表和目标表位于不同的数据库服务器中
执行存储过程时出现以下错误
必须声明标量变量" @ startYear"。
以下是存储过程。有谁能告诉我这是什么问题?
CREATE PROCEDURE processFinancialStatementIds
AS
BEGIN
set nocount on
declare @startYear int, @startQuarter int, @sql nvarchar(max), @tableName varchar(50);
set @startYear = 2000;
set @startQuarter = 1;
while(@startYear < 2018)
begin
set @startQuarter = 1;
while(@startQuarter < 5)
begin
set @tableName = 'FinData' + cast(@startYear as varchar) + '_' + cast(@startQuarter as varchar);
set @sql = '
EXECUTE (''USE CoreReferenceStaging;drop table [dbo].[' + @tableName + '];'') AT [GBIPS-I-DB324D];
EXECUTE (''USE CoreReferenceStaging;create table [dbo].[' + @tableName + '] ( calendarYear int, calendarQuarter int, companyid bigint not null, dataitemid bigint not null, dataitemvalue numeric(28,6), fiscalyear int, fiscalquarter int, periodenddate datetime, filingdate datetime, latestforfinancialperiodflag bit, latestfilingforinstanceflag bit );'') AT [GBIPS-I-DB324D]
EXECUTE (''USE CoreReferenceStaging;
insert into [dbo].[' + @tableName + '] select fp.calendarYear, fp.calendarQuarter, fp.companyid, fd.dataitemid, fd.dataitemvalue, fp.fiscalyear, fp.fiscalquarter, fi.periodenddate, fi.filingdate, fi.latestforfinancialperiodflag, fi.latestfilingforinstanceflag
from [Xpressfeed_dev].[dbo].[ciqFinPeriod] fp
inner join [Xpressfeed_dev].[dbo].[ciqFinInstance] fi on fi.financialPeriodId = fp.financialPeriodId
inner join [Xpressfeed_dev].[dbo].[ciqFinInstanceToCollection] fc on fc.financialInstanceId = fi.financialInstanceId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollection] c on c.financialCollectionId = fc.financialCollectionId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollectionData] fd on fd.financialCollectionId = c.financialCollectionId
where YEAR(fi.periodenddate) = cast(@startYear as varchar) and DATEPART( quarter,fi.periodenddate) = cast(@startQuarter as varchar '') AT [GBIPS-I-DB324D]'
--print (@sql);
EXEC sp_executesql @sql
set @startQuarter += 1
end
set @startYear += 1;
end
end
修改后的查询
BEGIN
set nocount on
--declare @startYear int, @startQuarter int, @sql nvarchar(max), @tableName varchar(50);
--set @startYear = 2000;
--set @startQuarter = 1;
declare @startyear int = 2000
declare @startQuarter int = 1
declare @sql nvarchar(max)
declare @tableName varchar(50)
while @startYear < 2018
begin
set @startQuarter = 1;
while @startQuarter < 5
begin
set @tableName = 'FinData' + cast (@startYear as varchar) + '_' + cast(@startQuarter as varchar);
set @sql = '
EXECUTE (''USE CoreReferenceStaging;drop table [dbo].[' + @tableName + '];'') AT [GBIPS-I-DB324D];
EXECUTE (''USE CoreReferenceStaging;create table [dbo].[' + @tableName + '] ( calendarYear int, calendarQuarter int, companyid bigint not null, dataitemid bigint not null, dataitemvalue numeric(28,6), fiscalyear int, fiscalquarter int, periodenddate datetime, filingdate datetime, latestforfinancialperiodflag bit, latestfilingforinstanceflag bit );'') AT [GBIPS-I-DB324D]
EXECUTE (''USE CoreReferenceStaging;
insert into [dbo].[' + @tableName + '] select fp.calendarYear, fp.calendarQuarter, fp.companyid, fd.dataitemid, fd.dataitemvalue, fp.fiscalyear, fp.fiscalquarter, fi.periodenddate, fi.filingdate, fi.latestforfinancialperiodflag, fi.latestfilingforinstanceflag
from [Xpressfeed_dev].[dbo].[ciqFinPeriod] fp
inner join [Xpressfeed_dev].[dbo].[ciqFinInstance] fi on fi.financialPeriodId = fp.financialPeriodId
inner join [Xpressfeed_dev].[dbo].[ciqFinInstanceToCollection] fc on fc.financialInstanceId = fi.financialInstanceId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollection] c on c.financialCollectionId = fc.financialCollectionId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollectionData] fd on fd.financialCollectionId = c.financialCollectionId
where YEAR(fi.periodenddate) = cast(@startYear as varchar) and DATEPART( quarter,fi.periodenddate) = cast(@startQuarter as varchar '') AT [GBIPS-I-DB324D]'
--print (@sql);
EXEC sp_executesql @sql
set @startQuarter += 1
end
set @startYear += 1;
end
end
答案 0 :(得分:0)
您不需要声明它两次,但是您必须将变量@startYear用作变量而不是固定值,方法是将它放在括号之外。请参阅下面的简化示例。
declare @startyear int = 2015
declare @startQuarter int = 1
declare @statement nvarchar(max)
while @startyear < 2017
begin
set @startQuarter=1
while @startQuarter < 5
begin set @statement = 'The year is '+cast(@startyear as varchar)+', the month is '+cast(@startQuarter as varchar)
print @statement
set @startQuarter += 1
end
set @startyear +=1
end
在您的脚本中,这将导致:
BEGIN
set nocount on
declare @startyear int = 2000
declare @startQuarter int = 1
declare @sql nvarchar(max)
declare @tableName varchar(50)
while @startYear < 2018
begin
set @startQuarter = 1;
while @startQuarter < 5
begin
set @tableName = 'FinData' + cast (@startYear as varchar) + '_' + cast(@startQuarter as varchar);
set @sql = '
EXECUTE (''USE CoreReferenceStaging;drop table [dbo].[' + @tableName + '];'') AT [GBIPS-I-DB324D];
EXECUTE (''USE CoreReferenceStaging;create table [dbo].[' + @tableName + '] ( calendarYear int, calendarQuarter int, companyid bigint not null, dataitemid bigint not null, dataitemvalue numeric(28,6), fiscalyear int, fiscalquarter int, periodenddate datetime, filingdate datetime, latestforfinancialperiodflag bit, latestfilingforinstanceflag bit );'') AT [GBIPS-I-DB324D]
EXECUTE (''USE CoreReferenceStaging;
insert into [dbo].[' + @tableName + '] select fp.calendarYear, fp.calendarQuarter, fp.companyid, fd.dataitemid, fd.dataitemvalue, fp.fiscalyear, fp.fiscalquarter, fi.periodenddate, fi.filingdate, fi.latestforfinancialperiodflag, fi.latestfilingforinstanceflag
from [Xpressfeed_dev].[dbo].[ciqFinPeriod] fp
inner join [Xpressfeed_dev].[dbo].[ciqFinInstance] fi on fi.financialPeriodId = fp.financialPeriodId
inner join [Xpressfeed_dev].[dbo].[ciqFinInstanceToCollection] fc on fc.financialInstanceId = fi.financialInstanceId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollection] c on c.financialCollectionId = fc.financialCollectionId
inner join [Xpressfeed_dev].[dbo].[ciqFinCollectionData] fd on fd.financialCollectionId = c.financialCollectionId
where YEAR(fi.periodenddate) = cast(' + @startYear + 'as varchar) and DATEPART( quarter,fi.periodenddate) = cast(' + @startQuarter + ' as varchar '') AT [GBIPS-I-DB324D]'
--print (@sql);
EXEC sp_executesql @sql
set @startQuarter += 1
end
set @startYear += 1;
end
end