Цикл while SQL со скалярными переменными - PullRequest
0 голосов
/ 17 декабря 2018

Я уже запускал этот тип кода несколько раз, но в другой среде в другой организации и не совсем в тех же версиях на 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 голосов
/ 17 декабря 2018

Для выполнения динамического 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
0 голосов
/ 17 декабря 2018

Как насчет

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;

Я не понимаю, почему вам нужно использовать цикл здесь

Смотрите результаты здесь

0 голосов
/ 17 декабря 2018

Я бы написал так:

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;
...