2017-05-30 91 views
-1

我有一个存储过程,对日期范围的需要:与转换日期存储过程

Create Procedure Search_PO 
(
@usersID CHAR(10), 
@poNo VARCHAR(20), 
@poDateFrom Date, 
@poDateTo Date, 
) 
As 
Begin 
    If (@poNo = '') 
    Begin 
    Set @poNo = Null 
    End 
    If (@poDateFrom = '01/01/0001') 
    Begin 
    Set @poDateFrom = Null 
    End 
    If (@poDateTo = '01/01/0001') 
    Begin 
    Set @poDateTo = Null 
    End 

    Select * From PurchaseOrder p, Users u, Warehouse w 
    Where p.warehouseID = w.warehouseID 
    and w.usersID = u.usersID 
    and u.usersID = @usersID 
    and ((p.poNo like '%' + @poNo + '%') or @poNo Is Null) 
    and (p.poDate >= convert(date, @poDateFrom, 103) Or @poDateFrom Is Null) 
    and (p.poDate <= convert(date, @poDateTo, 103) Or @poDateTo Is Null) 
End 

这通常工作时,我已经选择日期,它是低于12(月数),它抛出我回来从varchar转换的误差为date

我相信这是由于这样的事实:

  1. 在SQL Server的日期格式为MM/DD/YYYY
  2. 0在Visual Studio
  3. 日期格式为DD/MM/YYYY

我使用此代码作为一个独立的代码来检查,如果我的转换正在尝试:

select * from PurchaseOrder where poDate <= convert(date,'31/5/2017',103)

它的工作,但当我执行我的存储过程:

exec Search_PO 'US00000001','','1/1/0001','31/5/2017'

它返回我的转换错误AGA在。提前感谢您提供任何帮助。

+0

为什么你不能以明确的格式,如'yyyymmdd' ? – iamdave

+1

不要使用旧式连接语法! :) –

+0

转换(日期,@日期,101) – Ravi

回答

0

您目前正在将两个日期参数转换两次 - 一次在procdeure声明中(隐式地)并且一次在您的select语句中(明确地)。在存储过程声明中将@poDateFrom和@poDateTo参数隐式转换为日期时,您的过程失败。如果您无法控制传递到您的过程的日期格式,则应将参数类型更改为varchar。

ALTER Procedure Search_PO 
(
@usersID CHAR(10), 
@poNo VARCHAR(20), 
@poDateFrom VARCHAR(10), 
@poDateTo VARCHAR(10), 
) 

这将避免隐式转换,只有在你显式转换依赖(即转换(日期,@poDateFrom,103)),正如你已经显示,将工作的字符串值'31/5/2017'

+0

我不同意你的建议,OP应该使用正确的数据类型并且不依赖任何转换。 –

+0

这是真的,但在这种特殊情况下,我提供了一个解释,为什么他在执行存储过程时看到转换错误,而不是使用直接传递给convert函数的字符串运行select语句。 – user3656388

+0

解释没有错,你做得很好,我只是不同意字符串应该作为'VARCHAR(10)'传递,就是这样;) –

2

我认为这个问题是在

exec Search_PO 'US00000001','','1/1/0001','31/5/2017' 

你应该通过日期类型参数上yyyymmddyyyy-mm-dd格式,而不是dd/mm/yyyy。 将其更改为:

exec Search_PO 'US00000001','','1/01/01','2017/05/31' 

而且你也不需要转换convert(date, @poDateFrom, 103),其类型为DATE了。

只是

and (p.poDate >= @poDateFrom Or @poDateFrom Is Null) 
and (p.poDate <= @poDateTo Or @poDateTo Is Null) 
+0

exec是正确的,我需要从Microsoft Visual Studio中输入日期的格式,这给了我的日期格式 –

1

你能发送日期为文本变量,然后让在存储过程中的转换?您可以使用SET DATEFORMAT dmy来确定SQL Server和Visual Studio日期格式。

经过这样的修改您的SP会是这样的:

Create Procedure Search_PO 
(
@usersID CHAR(10), 
@poNo VARCHAR(20), 
@poDateFrom_Chr VARCHAR(10), 
@poDateTo_Chr VARCHAR(10), 
) 
As 
Begin 

DECLARE @poDateFrom DATE 
DECLARE @poDateTo DATE 

SET DATEFORMAT dmy 
SET @poDateFrom = @poDateFrom_Chr 
SET @poDateTo = @poDateTo_Chr 
SET DATEFORMAT mdy 

If (@poNo = '') 
Begin 
Set @poNo = Null 
End 
If (@poDateFrom = '01/01/0001') 
Begin 
Set @poDateFrom = Null 
End 
If (@poDateTo = '01/01/0001') 
Begin 
Set @poDateTo = Null 
End 

Select * From PurchaseOrder p, Users u, Warehouse w 
Where p.warehouseID = w.warehouseID 
and w.usersID = u.usersID 
and u.usersID = @usersID 
and ((p.poNo like '%' + @poNo + '%') or @poNo Is Null) 
and (p.poDate >= convert(date, @poDateFrom, 103) Or @poDateFrom Is Null) 
and (p.poDate <= convert(date, @poDateTo, 103) Or @poDateTo Is Null) 

希望它能帮助。