标量变量的SQL while循环

时间:2018-12-17 12:04:32

标签: sql sql-server sql-server-2014 declare scalar

我之前已经运行过几次这种类型的代码,但是在另一个组织中的另一个环境中,而不是在SQL Server上完全相同的版本中。下面的示例代码已简化,但可以作为我的问题的示例。

在此示例中,我尝试进行几年的循环(“ ar”变量),并在另一个数据库中(而不是保存原始表的位置)每年创建一个新表。原始表包括所有年份。原始表中的“ ar”变量是一个整数。

我的代码如下:

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,第16级,状态2,第34行   名字 '   选择 *   进入MIRK3utv.dbo.Tab_2007   来自DBorg.dbo.OrgTab   其中ar = 2007'不是有效的标识符。

我在这里想念什么?我已经在网上和这个论坛上搜索了答案,但在这种情况下似乎找不到适合我的解决方案。

3 个答案:

答案 0 :(得分:3)

要执行动态SQL,您有两个选择:使用EXEC(@SQL)或使用EXEC sp_ExecuteSql @Sql
请注意,第一个选项包括括号-如果没有括号,SQL Server会假定您正在尝试执行存储过程-这就是为什么您会出错的原因。

您在问题中发布的代码也缺少将数据库名称与模式名称分隔开的点,但是它确实出现在错误消息中,因此我认为这只是问题本身的错字。

您可以像这样运行这段代码:

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

答案 1 :(得分:0)

我会这样写:

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;

答案 2 :(得分:0)

怎么样

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