【问题标题】:SQL Server stored procedure works but failes while running jobSQL Server 存储过程有效,但在运行作业时失败
【发布时间】:2018-03-15 01:30:43
【问题描述】:

我在 SQL Server 2017 Developer 中的存储过程存在问题。它使用xp_cmdshell 获取文件的修改日期,将varchar 返回到临时表中并尝试将其转换为日期。当我在 SSMS 中手动执行存储过程时,它正在工作,但是当我将它放入作业步骤时失败。

作业历史错误:

从字符串转换日期和/或时间时转换失败。 [SQLSTATE 22007](错误 241)

我已经标记了失败的代码片段(当我试图在没有这个的情况下在作业中执行 SP 时,它执行成功)。

当我只执行“问题”代码时,它工作正常并返回这样的数据:

代码:

select top(1) cast(left(mdate,20) as date) data_ 
from t_lomag_temp_table

结果:

2018-03-14

存储过程代码:

declare @lomag_bak_file_source nvarchar(400) = /*source folder*/
declare @restore_status int
declare @bak_list as table (id int identity
                          , plik varchar(200)
                          , data_bak date)
declare @baza_nazwa varchar(200)
declare @xp_cmdshell_dir varchar(1000)
declare @counter int
declare @loop_limit int
declare @bak_files_status int

set @restore_status = 0
set @bak_files_status = 0
set @counter = 1
;

truncate table t_lomag_temp_table
;

insert into @bak_list
    select concat(dl.baza,'_db.bak'), null
    from t_lomag_database_list dl
;

select @loop_limit = max(id) from @bak_list

while @counter <= @loop_limit
begin
    select @baza_nazwa = bl.plik 
    from @bak_list bl 
    where bl.id = @counter

    set @xp_cmdshell_dir = concat('dir ',@lomag_bak_file_source,@baza_nazwa)

    insert t_lomag_temp_table 
        exec master.dbo.xp_cmdshell @xp_cmdshell_dir

    set rowcount 5 

    delete from t_lomag_temp_table 

    set rowcount 0

    /* JOB PROBLEM CODE varchar to date*/
    update @bak_list 
    set data_bak = x.data_ 
    from (select top(1) cast(left(mdate, 20) as date) data_
          from t_lomag_temp_table) x
    where @baza_nazwa = plik

    set @counter = @counter + 1
end
;

begin transaction

delete from logistyka.dbo.t_lomag_restore_dates

commit transaction
;

begin transaction
    insert into logistyka.dbo.t_lomag_restore_dates
        select 
            plik, data_bak, 1, 0
        from 
            @bak_list
    ;

    select @bak_files_status = min(rd.date_status_fl)
    from logistyka.dbo.t_lomag_restore_dates rd
;

commit transaction
;

【问题讨论】:

    标签: sql sql-server tsql stored-procedures sql-server-agent


    【解决方案1】:

    你的约会很糟糕。您可以使用try_convert()try_cast() 找到它:

    select mdate
    from t_lomag_temp_table
    where try_convert(date, left(mdate, 20)) is null;
    

    您的代码成功了,因为它 - 大概 - 很容易在表格中找到有效日期。存储过程失败,因为它查看的值更多。

    【讨论】:

    • 存储过程在我使用 exec 过程运行时有效。只有当它被作业执行时才会失败。我更改了代码,现在它只在表中留下 1 行:“16.03.2018 00:05 129 410 560 filename.bak”然后我使用 cast(left(row,10) as date) 并返回:“2018-03 -11" 我尝试使用此值更新表,并且在"执行程序"中它可以工作。当我开始工作时,它失败并出现与以前相同的错误。
    • 好吧,我将日期保留为 varchar,并在程序中使用这种类型的日期。这是“sql 异端”,但它有效。
    【解决方案2】:

    只是为了踢球和咯咯笑,运行这个并查看是否返回了任何无法转换为日期(并引发错误)的值。如果是这样,那么找出如何优雅地处理这些值,或者通过运行 UPDATE 语句以使它们可日期转换,或者添加 WHERE 子句以将它们从查询中排除。

    选择日期 FROM t_lomag_temp_table WHERE ISDATE(left(mdate,20))= 0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多