我正在尝试创建一个存储过程。日期列使用varchar
数据类型。
我希望能够使用日期作为约束条件来选择数据。
ALTER PROCEDURE [dbo].[spStatusReport]
@ShipFrom VARCHAR(20) = NULL,
@ShipTo VARCHAR(20) = NULL,
AS
SELECT
LOCATION, NEXT_DEPT,
CAST(CONVERT(VARCHAR, REQ_DATE, 104) AS DATETIME) AS REQ_DATE,
CAST(CONVERT(VARCHAR, SCH, 104) AS DATETIME) AS SCH,
Tool
FROM
Status_Report
WHERE
(@ShipFrom IS NULL OR
CAST(CONVERT(VARCHAR, SCH, 104) AS DATETIME) >= CAST(CONVERT(VARCHAR, @ShipFrom, 104) AS DATETIME))
AND (@ShipTo IS NULL OR
CAST(CONVERT(VARCHAR, SCH, 104) AS DATETIME) <= CAST(CONVERT(VARCHAR, @ShipTo, 104) AS DATETIME))
当我尝试执行此存储过程时
exec spStatusReport '12/04/2018','NULL'
我希望用户只能传递一个参数ShipFrom或ShipTO或什至两者都传递
从字符串转换日期和/或时间时转换失败
答案 0 :(得分:2)
您传递的是文字字符串 'NULL'
,而不是值NULL
;他们不一样。另外,您应该使用ISO格式作为日期,这样就不会造成歧义。请尝试以下操作之一:
EXEC spStatusReport '20180412',NULL;
EXEC spStatusReport @ShipFrom = '20180412';
编辑:肖恩·兰格(Sean Lange)也在注释中。您的参数应该是date
,而不是varchar
。 始终使用适合您数据的数据类型。 varchar
远非“一刀切”的数据类型。
答案 1 :(得分:0)
您可以在where子句中执行类似的操作
declare @ShipFrom varchar(20) =NULL,
@ShipTo varchar(20)= NULL
--set @ShipFrom = getdate() - 1
--set @ShipTo = getdate()
select isnull(@ShipFrom,getdate() - 1) , isnull(@ShipTo,getdate())
答案 2 :(得分:0)
我强烈建议您将日期/时间值传递为date
/ datetime
或相关数据类型。
然后,请勿转换为字符串以删除时间分量。 SQL Server具有更好的机制。并且不要将字符串转换为字符串;只是没有道理。
您还可以在适当的地方使用try_convert()
:
ALTER PROCEDURE [dbo].[spStatusReport] (
@ShipFrom VARCHAR(20) = NULL,
@ShipTo VARCHAR(20) = NULL
) AS
BEGIN
SELECT
LOCATION, NEXT_DEPT,
CAST(CAST(REQ_DATE AS DATE) AS DATETIME) AS REQ_DATE,
CAST(CAST(SCH AS DATE) AS DATETIME) AS DATETIME) AS SCH,
Tool
FROM Status_Report
WHERE (@ShipFrom IS NULL OR
TRY_CONVERT(DATE, SCH, 104 >= TRY_CONVERT(DTAE, @ShipFrom, 104)
) AND
(@ShipTo IS NULL OR
TRY_CONVERT(DATE, SCH, 104) <= TRY_CONVERT(DATE, @ShipTo, 104)
);
END;