用于从视图创建表的MSSQL Dynamic SQL仅在通过作业执行时才会失败

时间:2018-05-24 11:21:31

标签: sql sql-server sql-server-2012 dynamic-sql

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

我的方法是,对于每个视图,应该创建一个表,因此我用动态SQL实现了它。因此,每次添加视图时,我都不必触摸工作。

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

该错误表明它无法将nvarchar类型转换为日期时间类型。 我检查了每个视图并单独为每个视图/表运行代码以及一次性运行并且没有错误。

有谁知道这里有什么问题?

以下是我使用的动态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 :(得分:0)

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

exec my_proc @my_param='20180524'

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

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

答案 1 :(得分:0)

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