SQL while 带标量变量的循环
SQL while loop with scalar variables
我以前 运行 多次使用过这种类型的代码,但是在另一个组织的另一个环境中,而不是 SQL 服务器上的完全相同的版本。下面的示例代码经过了简化,但它可以作为我的问题的示例。
在这个例子中,我试图在几年内做一个循环("ar" 变量)并在另一个数据库中每年创建一个新的 table 而不是原来的 [=26] =] 已保存。原来 table 包括所有年份。原来table中的"ar"变量是一个int。
我的代码如下所示:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + 'dbo.Tab_' + @ArVC + '
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec @CreateTable
set @Ar = @Ar + 1
end
这给我一个错误:
Msg 203, Level 16, State 2, Line 34
The name '
select *
into MIRK3utv.dbo.Tab_2007
from DBorg.dbo.OrgTab
where ar = 2007' is not a valid identifier.
我在这里错过了什么?我在网上和这个论坛上搜索了答案,但在这种情况下我似乎找不到适合我的解决方案。
我会这样写:
declare @Ar int = 2007;
declare @CreateTable nvarchar(MAX) = N''
declare @DB nvarchar(MAX)= N'MIRK3utv'
while @Ar <= 2015
begin
set @CreateTable = N'
select *
into ' + @DB + '.dbo.Tab_@Ar
from DBorg.dbo.OrgTab
where ar = @Ar';
set @CreateTable = replace(@CreateTable, @Ar);
exec sp_executesql @CreateTable
set @Ar = @Ar + 1
end;
要执行动态 SQL,您有两个选择:使用 EXEC(@SQL)
或使用 EXEC sp_ExecuteSql @Sql
。
请注意,第一个选项包括括号 - 没有它们,SQL 服务器假定您正在尝试执行存储过程 - 这就是您遇到错误的原因。
您在问题中发布的代码也缺少将数据库名称与模式名称分隔开的点,但它确实出现在错误消息中,因此我假设这只是问题本身的错字。
您可以运行这样的代码:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + '.dbo.Tab_' + @ArVC + ' -- added the missing dot
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec(@CreateTable) -- Note the parenthesis!
set @Ar = @Ar + 1
怎么样
DECLARE @SQL NVARCHAR(MAX) = '';
WITH Years AS
(
SELECT 2007 Ar
UNION ALL
SELECT Ar + 1
FROM Years
WHERE Ar < 2015
)
SELECT @SQL = @SQL +
N'SELECT * INTO MIRK3utv.dbo.Tab_' +
CAST(Ar AS VARCHAR) +
' FROM DBorg.dbo.OrgTab WHERE Ar = ''' +
CAST(Ar AS VARCHAR) + '''; '
FROM Years;
SELECT @SQL;
--EXECUTE sp_executesql @SQL;
我不明白为什么你需要在这里使用循环
我以前 运行 多次使用过这种类型的代码,但是在另一个组织的另一个环境中,而不是 SQL 服务器上的完全相同的版本。下面的示例代码经过了简化,但它可以作为我的问题的示例。
在这个例子中,我试图在几年内做一个循环("ar" 变量)并在另一个数据库中每年创建一个新的 table 而不是原来的 [=26] =] 已保存。原来 table 包括所有年份。原来table中的"ar"变量是一个int。
我的代码如下所示:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + 'dbo.Tab_' + @ArVC + '
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec @CreateTable
set @Ar = @Ar + 1
end
这给我一个错误:
Msg 203, Level 16, State 2, Line 34 The name ' select * into MIRK3utv.dbo.Tab_2007 from DBorg.dbo.OrgTab where ar = 2007' is not a valid identifier.
我在这里错过了什么?我在网上和这个论坛上搜索了答案,但在这种情况下我似乎找不到适合我的解决方案。
我会这样写:
declare @Ar int = 2007;
declare @CreateTable nvarchar(MAX) = N''
declare @DB nvarchar(MAX)= N'MIRK3utv'
while @Ar <= 2015
begin
set @CreateTable = N'
select *
into ' + @DB + '.dbo.Tab_@Ar
from DBorg.dbo.OrgTab
where ar = @Ar';
set @CreateTable = replace(@CreateTable, @Ar);
exec sp_executesql @CreateTable
set @Ar = @Ar + 1
end;
要执行动态 SQL,您有两个选择:使用 EXEC(@SQL)
或使用 EXEC sp_ExecuteSql @Sql
。
请注意,第一个选项包括括号 - 没有它们,SQL 服务器假定您正在尝试执行存储过程 - 这就是您遇到错误的原因。
您在问题中发布的代码也缺少将数据库名称与模式名称分隔开的点,但它确实出现在错误消息中,因此我假设这只是问题本身的错字。
您可以运行这样的代码:
declare @Ar int = 2007
declare @ArVC varchar(4)=''
declare @CreateTable varchar(MAX)=''
declare @DB varchar(MAX)='MIRK3utv'
while @Ar <= 2015
begin
set @ArVC = cast(@Ar as varchar)
set @CreateTable = '
select *
into ' + @DB + '.dbo.Tab_' + @ArVC + ' -- added the missing dot
from DBorg.dbo.OrgTab
where ar = ' + @ArVC
exec(@CreateTable) -- Note the parenthesis!
set @Ar = @Ar + 1
怎么样
DECLARE @SQL NVARCHAR(MAX) = '';
WITH Years AS
(
SELECT 2007 Ar
UNION ALL
SELECT Ar + 1
FROM Years
WHERE Ar < 2015
)
SELECT @SQL = @SQL +
N'SELECT * INTO MIRK3utv.dbo.Tab_' +
CAST(Ar AS VARCHAR) +
' FROM DBorg.dbo.OrgTab WHERE Ar = ''' +
CAST(Ar AS VARCHAR) + '''; '
FROM Years;
SELECT @SQL;
--EXECUTE sp_executesql @SQL;
我不明白为什么你需要在这里使用循环