我在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
;
答案 0 :(得分:1)
你的约会不好。您可以使用try_convert()
或try_cast()
:
select mdate
from t_lomag_temp_table
where try_convert(date, left(mdate, 20)) is null;
您的代码成功,因为它可能很容易在表格中找到有效日期。存储过程失败,因为它会查看更多值。
答案 1 :(得分:0)
只是因为踢和咯咯地运行它,看看是否返回任何无法转换为日期(并抛出错误)的值。如果是这样,那么请弄清楚如何优雅地处理这些值,方法是运行UPDATE语句使它们可以进行日期转换,或者添加WHERE子句以从查询中排除它们。
SELECT mdate FROM t_lomag_temp_table WHERE ISDATE(左(mdate,20))= 0