2012-03-20 74 views
0

我有存儲過程。在它的正文中,我選擇了一些數據,其中一個字段爲nvarchar,但它包含日期(前18個符號只是文本,但後來是日期)。然後,我使用該日期與另一日期(已經是實際日期)進行比較的情況。SQL Server SqlClient奇怪的轉換異常

Select (bla bla) from (bla bla) 
where DATEDIFF(DAY,DueDateDay,CAST(SUBSTRING(myField,18,10) as datetime)) < @dayCount 

在SQL Server Management Studio中,此SP工作良好。但是,當我打電話從我的.net應用程序這個SP,使用SqlCommand.ExecuteReader()它拋出一個異常:

一個nvarchar數據類型爲日期時間數據類型 的轉換導致超出範圍的值。

原因?

SP:

ALTER PROCEDURE [dbo].[UK_GetPlanningDetails_test] 
     @itemStart nvarchar(30), 
     @itemEnd nvarchar(30), 
     @plan_codeStart nvarchar(3), 
     @plan_codeEnd nvarchar(3), 
     @arrivalDelay bit, 
     @demandDelay bit, 
     @negativeCount bit, 
     @arrivalMoveTo bit, 
     @arrivalMoveFrom bit, 
     @dayCount int, 
     @noNeedArrival bit, 
     @needAll bit, 
     @negativeOnSKZ bit = 0 
AS 
BEGIN 
    declare @sql nvarchar(2000); 
    declare @sql2 nvarchar(2000); 


    create table #temp 
    (
     Item nvarchar(30), 
     DueDateDay datetime, 
     description nvarchar(40), 
     plan_code nvarchar(3), 
     QtyOnHand nvarchar(40), 
     QtyReq nvarchar(40), 
     QtyRecv nvarchar(40), 
     ExceptMessage nvarchar(2800), 
     MrpRef nvarchar(2800), 
     LastChangedDate datetime 
    ) 

    create table #temp2 
    (
     Item nvarchar(30), 
     DueDateDay datetime, 
     description nvarchar(40), 
     plan_code nvarchar(3), 
     QtyOnHand nvarchar(40), 
     QtyReq nvarchar(40), 
     QtyRecv nvarchar(40), 
     ExceptMessage nvarchar(2800), 
     MrpRef nvarchar(2800), 
     LastChangedDate datetime 
    ) 

set @sql = N'SELECT o.Item, isnull(o.DueDateDay,''1950-01-01 00:00:00.000''), ISNULL(o.description,''''), isnull(o.plan_code,''''), convert(nvarchar(40),o.QtyOnHand), convert(nvarchar(40),o.QtyReq), convert(nvarchar(40),o.QtyRecv),isnull(o.ExceptMessage,''''), isnull(o.MrpRef,''''), isnull(o.LastChangedDate,''1950-01-01 00:00:00.000'') 
    FROM [std_app].[dbo].[PlanningDetailsView] i 
    left join [std_app].[dbo].[PlanningDetailsView] o on i.[Item]=o.[Item] 
    where (i.ExceptMessage is not null)' 

    if (@plan_codeStart<>'') set @[email protected]+ ' and (i.[plan_code] >= '''+ @plan_codeStart+''')' 
    if (@plan_codeEnd<>'') set @[email protected]+ ' and (i.[plan_code] <= '''+ @plan_codeEnd+''')' 
    if (@itemStart<>'') set @[email protected]+ ' and (i.[Item] >= '''+ @itemStart+''')' 
    if (@itemEnd<>'') set @[email protected]+ ' and (i.[Item] <= '''+ @itemEnd+''')' 

    if (@needAll<>1) 
     begin 
     if(@negativeOnSKZ=0) set @sql = @sql + ' and (i.MrpRef not like (''TPLN XFD-PLANT%'')) ' 
     set @sql [email protected] + 'and (' 

     if(@arrivalDelay<>0) set @sql = @sql + '(i.ExceptMessage like (''Задержка прогнозн.прихода%'')) or ' 
     if(@demandDelay<>0) set @sql = @sql + '(i.ExceptMessage like (''Задержка прогнозн.потребн.%'')) or ' 
     if(@negativeCount<>0) set @sql = @sql + '(i.ExceptMessage like (''Начал.колич.в наличии отрицательно%'')) or ' 
     if(@arrivalMoveTo<>0) set @sql = @sql + '(i.ExceptMessage like (''Перем.В Приход%'')) or ' 
     if(@noNeedArrival<>0) set @sql = @sql + '(i.ExceptMessage like (''Приход не требуется%'')) or ' 
     if(@negativeOnSKZ<>0) set @sql = @sql + '(i.MrpRef like (''TPLN XFD-PLANT%'')) or ' 

     set @sql [email protected] + '(i.ExceptMessage like('''')))' 

      if(@arrivalMoveFrom<>0) 
       begin 
       set @sql2 = N'SELECT Item, isnull(DueDateDay,''1950-01-01 00:00:00.000''), ISNULL(description,''''), isnull(plan_code,''''), convert(nvarchar(40),QtyOnHand), convert(nvarchar(40),QtyReq), convert(nvarchar(40),QtyRecv),isnull(ExceptMessage,''''), isnull(MrpRef,''''), isnull(LastChangedDate,''1950-01-01 00:00:00.000'') 
       FROM [std_app].[dbo].[PlanningDetailsView] 
       where (ExceptMessage is not null) 
       and (ExceptMessage like (''Перем.из прихода%''))' 

       if (@plan_codeStart<>'') set @[email protected]+ ' and ([plan_code] >= '''+ @plan_codeStart+''')' 
       if (@plan_codeEnd<>'') set @[email protected]+ ' and ([plan_code] <= '''+ @plan_codeEnd+''')' 
       if (@itemStart<>'') set @[email protected]+ ' and ([Item] >= '''+ @itemStart+''')' 
       if (@itemEnd<>'') set @[email protected]+ ' and ([Item] <= '''+ @itemEnd+''')' 

       insert into #temp2 execute(@sql2) 
       if(@dayCount>0) 
        begin 
        delete from #temp2 where DATEDIFF(DAY,DueDateDay,CAST(SUBSTRING(ExceptMessage,18,10) as datetime))<@dayCount 
        end 
       end 
     end 

    insert into #temp execute(@sql) 

    select my.*, StartDate = isnull(their.StartDate,'1950-01-01 00:00:00.000') from (select Item, DueDateDay, description, plan_code, QtyOnHand, QtyReq, QtyRecv, ExceptMessage, MrpRef, LastChangedDate from #temp 
    union 
    (
    select o.Item, o.DueDate, o.description, o.plan_code, o.QtyOnHand, o.QtyReq, o.QtyRecv, o.ExceptMessage, o.MrpRef, o.LastChangedDate 
    from #temp2 i left join [std_App].dbo.PlanningDetailsView o on i.Item = o.Item 
)) my 
    left join ( select 
    --- Four part key ----------------------- 
    --- Check performance before changing --- 
    apsplan.item as Item 
    , apsplan.due_date_day as DueDateDay 
    , 0 as QtyOnHand 
    , case when is_demand = 1 then apsplan.qty else 0 end as QtyReq 
    , case when is_demand = 1 then 0 else apsplan.qty end as QtyRecv 
    , case 
     when is_demand = 1 
     then case 
       when apsplan.ref_type = 'S' 
       then dbo.PPSRef(apsplan.ref_num, isnull(apsplan.ref_line_suf,0)) 
       else 
        case 
         WHEN apsplan.xref_num IS NOT NULL 
         THEN 'X' 
         ELSE '' 
        END + 
        CASE apsplan.ref_type 
         WHEN 'N' THEN 'PPLN ' 
         WHEN 'D' THEN 'TPLN ' 
         WHEN 'J' THEN 'PJOB ' 
         WHEN 'M' THEN 'PMPS ' 
         WHEN 'S' THEN 'PPS ' 
         WHEN 'C' THEN 'CO ' 
         ELSE '' 
        END + 
        CASE 
         WHEN apsplan.ref_num IS NOT NULL 
         THEN apsplan.ref_num 
         ELSE '' 
        END + 
        CASE 
         WHEN apsplan.ref_line_suf IS NOT NULL 
         THEN '-' + CAST(apsplan.ref_line_suf AS CHAR(4)) 
         ELSE '' 
        END + 
        CASE 
         WHEN apsplan.ref_rel IS NOT NULL 
         THEN '-' + SUBSTRING('000' + CAST(apsplan.ref_rel AS NVARCHAR), 
           LEN('000' + CAST(apsplan.ref_rel AS NVARCHAR)) -3, 4) 
ELSE '' 
        END 
       end 
     else 'PLN ' + apsplan.ref_num -- ORDER000.ORDERID 
    end 
    as MrpRef 
    , NULL as MrpExcept --dbo.GetMrpExcMesg(apsplan.item, apsplan.ref_type, apsplan.ref_num, apsplan.ref_line_suf, apsplan.ref_rel) 
    , apsplan.start_date as StartDate 
    FROM (
     select * 
     ,due_date as EndDate 
     ,ISNULL((select mp.ENDDATE 
        from apsplandetail 
        join MATLPLAN000 mp on mp.MATLTAG = apsplandetail.matltag and mp.PMATLTAG = 0 
        join ORDER000 o on o.ORDERID = mp.ORDERID and o.ORDTYPE = 310 -- Safety stock 
        where apsplan.RowPointer = apsplandetail.apsplan_reference), apsplan.due_date) 
      as ProjectedDate 
     from apsplan with(index(IX_apsplan_item_due_date_day)) 
     where apsplan.is_demand = 1 and apsplan.qty != 0 

     union all 

     select * 
     ,CASE WHEN SUBSTRING(apsplan.ref_num,1,3) = 'ROP' THEN apsplan.due_date 
       ELSE ISNULL ((select mp.NEEDDATE 
           from MATLPLAN000 mp 
           join ORDER000 o on o.ORDERID = mp.ORDERID and o.ORDTYPE = 310 -- Safety stock 
           where mp.MATLTAG = apsplan.ref_num and mp.PMATLTAG = 0), apsplan.due_date) 
       END as EndDate 
     ,due_date as ProjectedDate 
     from apsplan with(index(IX_apsplan_item_due_date_day)) 
     where apsplan.is_demand = 0 and apsplan.ref_type <> 'Z' 
    ) apsplan) their on their.Item=my.Item and my.MrpRef=their.MrpRef 

    where my.MrpRef not like case when @negativeOnSKZ=0 then ('TPLN XFD-PLANT%') else ('some unreal data') end or my.MrpRef like case when @negativeOnSKZ=1 then ('TPLN XFD-PLANT%') else ('some unreal data') end 
    order by my.item,my.DueDateDay 



    END 

CALL:

public static DataTable getTable(string connectionString, string SQLcommand) 
{ 
     SqlConnection Con = new SqlConnection(connectionString); 
     Con.Open(); 
     SqlCommand cmd1 = new SqlCommand(SQLcommand, Con); 
     cmd1.CommandTimeout = 5 * 60 * 1000; 
     SqlDataReader Read1 = cmd1.ExecuteReader(); 
     DataTable getTab = new DataTable(); 
     getTab.Load(Read1); 
     Con.Close(); 
     return getTab; 
} 

SQLcommand = EXEC [dbo].[UK_GetPlanningDetails_test] @itemStart = N'', @itemEnd = N'', @plan_codeStart = N'', @plan_codeEnd = N'', @arrivalDelay = 0 , @demandDelay = 0 , @negativeCount = 0 , @arrivalMoveTo = 0 , @arrivalMoveFrom = 1 , @dayCount = 10 , @noNeedArrival = 0 , @needAll = 0 , @negativeOnSKZ = 0 
+0

你確定它在這是造成的轉換失敗的程序CAST?你有沒有參數傳入過程? – kaj 2012-03-20 06:21:02

+0

它是該proc中唯一的地方,其中轉換使用 多於它使用相同的參數從msqsqlsms – StNickolas 2012-03-20 06:23:51

+0

您可以告訴我們您的存儲過程,以及調用它的代碼嗎? – tobias86 2012-03-20 06:26:58

回答

0

我想在字符串中的日期格式是不妥當的。在SQL Server Management Studio中工作而不在.Net中工作的原因可能是連接languge。

第一選擇的作品,但SECEND給出相同exeption

SET LANGUAGE us_english 
select CAST('12.18.2012' as datetime) 

SET LANGUAGE turkish 
select CAST('12.18.2012' as datetime)