仅当通过作业执行时,用于从视图创建表的MSSQL动态SQL才会失败

仅当通过作业执行时,用于从视图创建表的MSSQL动态SQL才会失败,sql,sql-server,sql-server-2012,dynamic-sql,Sql,Sql Server,Sql Server 2012,Dynamic Sql,我在创建周期表时遇到问题。 我有很多视图需要写入到表中 我的方法是,对于存在的每个视图,都应该创建一个表,因此我使用动态SQL实现了它。这样,我就不必每次添加视图时都要触摸作业 我的问题是,只要我自己在SSSM中执行,代码就可以正常工作。 一旦我把它放到一个作业中,并且它是按计划或由我自己执行的,它就失败了。如果我用动态SQL生成的代码替换它,那么作业也会失败。我甚至将代码放入一个存储过程中,然后从作业中执行该过程,从而产生相同的结果 该错误表示无法将nvarchar类型转换为datetime类

我在创建周期表时遇到问题。 我有很多视图需要写入到表中

我的方法是,对于存在的每个视图,都应该创建一个表,因此我使用动态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);

在作业中,是否使用日期文本调用存储的过程,如:

exec my_proc @my_param='20180524'
??你不能这样做。首先将值分配给var,然后使用var:

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

此SQL未经测试,但是,这应该对您有很大帮助。请注意,我分别执行每个执行。首先,这(实际上)意味着,如果动态SQL失败,它将不会传播出去(然而,这可能不是有意的)。不过,我还添加了
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;

我猜问题在于
视图
,而不是动态SQL。与其尝试一次性完成所有操作,实际上我建议在这里使用
光标
(是的,没错,我建议使用
光标
)。然后添加一些
PRINT
语句来帮助调试SQL
打印
项,如
@SQL
的值和将用于创建新
表的
视图的名称。你会发现有问题的
视图
并可以调试它。我只执行了每个视图,没有一个是问题。正如我所说,当我自己在SSSM中执行代码时,它工作得很好。我相当确信,您发布的代码不会因为您提供的错误而失败,因为它所做的只是
删除表
选择到
,两者都不涉及转换。你必须找出它实际失败的地方。这可能是一些模糊的东西,比如DDL触发器。它还可能涉及架构不匹配之类的问题(例如,根据您登录的帐户,您并不总是谈论您认为正在谈论的相同对象)。哦,等等,我忽略了显而易见的问题-P当然,您执行的
SELECT
语句可能会失败,这取决于视图中的内容。一个用户完全有可能从一个视图中获得不同的数据或不同的错误,这取决于生成的查询计划(这反过来也取决于
SET
选项,这在SSM和其他客户端之间也可能有所不同)。您应该做的是以该语句失败的用户身份登录,并检查每个
SELECT。。在每个视图上的
语句中查找可能的故障。但是如果我通过“在步骤开始作业”执行作业,那么它将在我的用户下运行,对吗?它也会因作业按计划执行而失败。我想我不能使用那个“用户”。SP中只有上面的代码,没有任何参数。我现在发现哪个视图最有可能导致问题。无论哪种方式,作业本身都失败了,但我想这是因为其中一个视图在执行过程中引发了错误。非常感谢你的代码!为了完全理解所有的命令,我需要学习很多东西,但我一直想做类似的事情