FUNCTION中的VARCHAR比较

时间:2013-11-07 12:51:48

标签: sql-server compare varchar

我有以下功能:

CREATE FUNCTION ISRELKDVG(@WUNSCH_LIEFERTERMIN VARCHAR) RETURNS int AS
BEGIN
    DECLARE @sTerminNone VARCHAR(8)
    DECLARE @sTerminFrom VARCHAR(8)
    SET @sTerminNone = '00000000'
    SET @sTerminFrom = CONVERT(VARCHAR(8), GETDATE() - 100, 112) -- 100 days in the past
    IF (@WUNSCH_LIEFERTERMIN <> @sTerminNone AND @WUNSCH_LIEFERTERMIN >= @sTerminFrom)
        RETURN 1
    RETURN 0
END

作为函数参数给出的变量是一个日期,其格式为“YYYYMMDD”。问题是函数永远不会返回1.

我发现link表示将varchar与未指定的长度进行比较可能会导致错误。它是否也引用传递给函数的varchar?

4 个答案:

答案 0 :(得分:0)

不要依赖隐式转换,使用未知的日期格式。转换为日期或日期时间,指定dateformat,并比较这些值。

答案 1 :(得分:0)

是的,这是主要问题。

<强> MSDN - Remarks

  

在数据定义或变量声明中未指定n时   声明,默认长度为1.使用时未指定n   CAST和CONVERT函数,默认长度为30。

但是(即使在转换/转换的情况下),您应该始终定义长度以避免此类麻烦。

更改

@WUNSCH_LIEFERTERMIN VARCHAR --<--Length is 1 by default

@WUNSCH_LIEFERTERMIN VARCHAR(8) --Or length as appropriate

其次,您应该比较Dates 而不是 Strings

DECLARE @sTerminNone DATE = CONVERT(DATETIME, 0) --<--DATE (Assign correct date)
DECLARE @sTerminFrom DATE = GETDATE() - 100

最后,

IF (CONVERT(DATE, @WUNSCH_LIEFERTERMIN, 112) <> @sTerminNone AND --Not sure if you need this
    CONVERT(DATE, @WUNSCH_LIEFERTERMIN, 112) >= @sTerminFrom)
    RETURN 1
ELSE
    RETURN 0

理想情况下,您应该将DateType parameter传递给函数。

答案 2 :(得分:0)

指定函数参数的大小,例如VARCHAR(8)。否则默认为1个字符:

declare @c as varchar
set @c = '20130101'
select @c -- returns 2

答案 3 :(得分:0)

试试这个:

CREATE FUNCTION ISRELKDVG(@WUNSCH_LIEFERTERMIN VARCHAR(8)) RETURNS int AS
BEGIN
    DECLARE @sTerminNone VARCHAR(8)
    DECLARE @sTerminFrom DATE
    SET @sTerminNone = '00000000'

    IF (@WUNSCH_LIEFERTERMIN = @sTerminNone)
        RETURN 0

    SET @sTerminFrom = DATEADD(day,-100,GETDATE()) -- 100 days in the past
    IF (CAST(@WUNSCH_LIEFERTERMIN AS DATE) >= @sTerminFrom)
        RETURN 1

    RETURN 0          
END

select dbo.ISRELKDVG('00000000') --0
select dbo.ISRELKDVG('20030901') --0
select dbo.ISRELKDVG('20130901') --1
select dbo.ISRELKDVG('20130730') --1