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;

我不明白为什么你需要在这里使用循环

See the results here