MSSQL Динамический SQL для создания таблицы из представления завершается ошибкой только при выполнении через задание - PullRequest
0 голосов
/ 24 мая 2018

У меня проблема с созданием повторяющейся таблицы.У меня есть куча взглядов, которые нужно записать в таблицы.

Мой подход заключается в том, что для каждого представления должна быть создана таблица, и поэтому я понял это с помощью динамического SQL.Так что мне не нужно прикасаться к работе каждый раз, когда я добавляю представление.

Моя проблема в том, что код работает нормально, пока я сам выполняю его в SSSM.Как только я помещаю это в работу, и это выполнено по расписанию или самостоятельно, это терпит неудачу.Если я заменю динамический SQL кодом, который он производит, задание также завершится неудачно.Я даже поместил код в хранимую процедуру и просто выполнил его из задания, и он дал тот же результат.

В сообщении об ошибке говорится, что он не может преобразовать тип nvarchar в тип datetime.Я проверил каждое представление и запустил код для каждого представления / таблицы по отдельности, а также сразу, и ошибки не было.

Кто-нибудь знает, что здесь не так?

Вот код динамического SQL, который я использую:

DECLARE @SQL varchar(max);

SELECT @SQL = COALESCE(@SQL + ' ', '') + 'IF OBJECT_ID(''' + REPLACE(name, 'qry_', 'tbl_') + ''', ''U'') IS NOT NULL DROP TABLE ' + QUOTENAME(REPLACE(name, 'qry_', 'tbl_')) + ';  SELECT * INTO ' + QUOTENAME(REPLACE(name, 'qry_', 'tbl_')) + ' FROM ' + QUOTENAME(name) + ';'
FROM sys.views
WHERE LEFT(name, 4) = 'qry_'

EXEC (@sql);

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Этот SQL не проверен, однако, это должно вам сильно помочь.Обратите внимание, что я делаю каждое исполнение отдельно.Во-первых, это (на самом деле) означает, что если динамический SQL завершится неудачно, он не будет распространяться (однако, это может быть не так).Я также добавил операторы PRINT, чтобы вы могли просматривать журналы и видеть, что на самом деле было сделано;и какой вид был провален.PRINT @SQL; закомментировано, поскольку (если я правильно помню) журналы агента могут содержать только 8000 или 4000 символов, поэтому печать значения @SQL приведет к его переполнению.

DECLARE @SQL nvarchar(MAX), @ViewName sysname;

DECLARE qry_views CURSOR FOR
SELECT [name]
FROM sys.views
WHERE [name] LIKE 'qry[_]%'

OPEN qry_views;

FETCH NEXT FROM qry_views
INTO @ViewName;

WHILE @@FETCH_STATUS = 0 BEGIN

    PRINT 'Creating table from View ' + QUOTENAME(@ViewName);

    SET @SQL = N'IF OBJECT_ID(''' + REPLACE(@ViewName, N'qry_', N'tbl_') + N''', ''U'') IS NOT NULL DROP TABLE ' + QUOTENAME(REPLACE(@ViewName, N'qry_', N'tbl_')) + N';' + NCHAR(10) + 
               N'SELECT *' + NCHAR(10) +
               N'INTO ' + QUOTENAME(REPLACE(@ViewName, N'qry_', N'tbl_')) + NCHAR(10) +
               N'FROM ' + QUOTENAME(@ViewName) + N';';

    --PRINT @SQL;

    EXEC sp_executesql @SQL;

    FETCH NEXT FROM qry_views
    INTO @ViewName;

END

CLOSE qry_views;
DEALLOCATE qry_views;
0 голосов
/ 24 мая 2018

В работе вы вызываете сохраненный процесс, используя литералы даты, например:

exec my_proc @my_param='20180524'

?Вы не можете сделать это.Вначале присваивая значения переменной, затем используйте переменную:

declare @my_value date ='20180524'
exec my_proc @my_param=@my_value
...