Sql 从字符串转换日期时间时发生转换错误
我正在尝试创建一个存储过程。日期列使用Sql 从字符串转换日期时间时发生转换错误,sql,sql-server,Sql,Sql Server,我正在尝试创建一个存储过程。日期列使用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 D
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))
我希望用户只能传递ShipFrom或ShipTO或两者中的一个参数,但我得到了这个错误
从字符串转换日期和/或时间时转换失败
您传递的是文本字符串
'NULL'
而不是值NULL
;他们不一样。此外,您应该使用ISO格式的日期,这样它就不会模棱两可。请尝试以下操作之一:
EXEC spStatusReport '20180412',NULL;
EXEC spStatusReport @ShipFrom = '20180412';
编辑:肖恩·兰格的评论也是对的。您的参数应该是
date
,而不是varchar
始终使用适合您的数据的数据类型varchar
远远不是“一刀切”的数据类型。您传递的是文本字符串'NULL'
而不是值NULL
;他们不一样。此外,您应该使用ISO格式的日期,这样它就不会模棱两可。请尝试以下操作之一:
EXEC spStatusReport '20180412',NULL;
EXEC spStatusReport @ShipFrom = '20180412';
编辑:肖恩·兰格的评论也是对的。您的参数应该是
date
,而不是varchar
始终使用适合您的数据的数据类型varchar
远远不是“一刀切”的数据类型。您可以在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())
您可以在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())
我强烈建议您将日期/时间值作为
date
/datetime
或相关数据类型传递
然后,不要转换为字符串来删除时间组件。SQLServer有更好的机制。不要将字符串转换为字符串;这根本没有道理
您也可以在适当的情况下使用try\u 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;
ALTER过程[dbo].[spStatusReport](
@ShipFrom VARCHAR(20)=空,
@ShipTo VARCHAR(20)=空
)作为
开始
挑选
地点,下一个部门,
CAST(CAST(要求日期为日期)为要求日期,
转换(转换(SCH为日期)为日期时间)为日期时间)为SCH,
工具
从状态报告
其中(@ShipFrom为NULL或
TRY_CONVERT(日期,SCH,104>=TRY_CONVERT(DTAE,@ShipFrom,104)
)及
(@ShipTo为空或
尝试转换(日期,SCH,104)我强烈建议您将日期/时间值作为DATE
/datetime
或相关数据类型传递
然后,不要转换为字符串来删除时间组件。SQL Server有更好的机制。不要将字符串转换为字符串;这根本没有意义
您也可以在适当的情况下使用try\u 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;
ALTER过程[dbo].[spStatusReport](
@ShipFrom VARCHAR(20)=空,
@ShipTo VARCHAR(20)=空
)作为
开始
挑选
地点,下一个部门,
CAST(CAST(要求日期为日期)为要求日期,
转换(转换(SCH为日期)为日期时间)为日期时间)为SCH,
工具
从状态报告
其中(@ShipFrom为NULL或
TRY_CONVERT(日期,SCH,104>=TRY_CONVERT(DTAE,@ShipFrom,104)
)及
(@ShipTo为空或
尝试转换(日期,SCH,104)。如果SHIPTO参数为null,则可以设置默认参数,如getdate();如果SHIPFROM为null,则可以设置默认参数,如getdate()-1您的参数是varchar而不是dates。这使得这比需要的要痛苦得多。从使用正确的数据类型开始。我甚至没有注意到varchar
声明。/facepalm您可以检查下面的示例代码;如果其中一个或两个参数都为NULL,则设置默认值。您可以在开始时使用IF st检查这一点atement。确保使用BEGIN、END来封装IF-语句。如果SHIPTO param为null,则可以设置默认参数,如getdate();如果SHIPFROM为null,则可以设置类似(getdate()-1)的默认参数您的参数是varchar而不是dates。这使得这比需要的要痛苦得多。从使用正确的数据类型开始。我甚至没有注意到varchar
声明。/facepalm您可以检查下面的示例代码;如果其中一个或两个参数都为NULL,则设置默认值。您可以在开始时使用IF st检查这一点atement。确保使用BEGIN、END来封装IF语句。我实际上是使用一个C#web应用程序来执行此操作的,执行查询的过程就是这样default@Saahar不,C没有。它肯定不会传递值NULL
的文本字符串'NULL'
。这听起来像是你的C代码的问题,不是吗我实际上是使用一个C#web应用程序来执行这项操作,以执行这样的查询过程default@Saahar不,C没有。它肯定不会传递值NULL
的文本字符串'NULL'
。这听起来像是你的C代码的问题,而不是SQL。