转换日期为

时间:2017-05-30 09:35:40

标签: sql-server tsql date stored-procedures

我有一个存储过程,其中包含日期范围:

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. Visual Studio中的日期格式为dd / mm / yyyy
  3. 我尝试将此代码用作独立代码,以检查我的转换是否正常:

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

    它确实有效,但是当我执行我的存储过程时:

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

    它再次返回转换错误。提前感谢您提供任何帮助。

3 个答案:

答案 0 :(得分:2)

我认为问题在于

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

您应该以{{1​​}}或yyyymmdd格式传递日期类型参数,而不是yyyy-mm-dd。 将其更改为:

dd/mm/yyyy

而且您不需要转换exec Search_PO 'US00000001','','1/01/01','2017/05/31' ,其类型已经是DATE。

convert(date, @poDateFrom, 103)

答案 1 :(得分: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) 

结束

希望它有所帮助。

答案 2 :(得分:0)

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

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

这将避免隐式转换,并且仅依赖于您的显式转换(即转换(日期,@ poDateFrom,103)),正如您已经显示的那样,它将用于字符串值&#39; 31 / 2017分之5&#39;