MSSQL Dynamic SQL for table 从视图创建仅在通过作业执行时失败

MSSQL Dynamic SQL for table creation from view fails only when executed through job

我的重复 table 创建有问题。 我有一堆视图需要写入 tables。

我的方法是,对于每个视图,都应该创建一个 table,因此我用动态 SQL 实现了它。这样我就不用在每次添加视图的时候都去碰作业了。

我的问题是,只要我在 SSSM 中自己执行代码,代码就可以正常工作。 一旦我将其放入工作中并按计划执行或由我自己执行,它就会失败。如果我用它生成的代码替换动态 SQL ,作业也会失败。我什至将代码放入存储过程并从作业中执行它并产生相同的结果。

错误指出无法将 nvarchar 类型转换为 datetime 类型。 我检查了每个视图和 运行 每个 view/table 的代码,一次也检查了所有,没有错误。

有人知道这里出了什么问题吗?

这是我使用的动态 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);

在工作中,您是否使用日期文字调用存储过程,例如:

exec my_proc @my_param='20180524'

?你不能这样做。首先将值分配给 var,然后使用 var:

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

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