用于抑制' 1900-01-01 00:00:00.000'的默认值的存储过程

时间:2014-08-05 19:51:54

标签: sql sql-server case

所以我正在使用一个使用默认日期值'1900-01-01 00:00:00.000'而不是允许空值的系统。我有一个存储过程,显示一个关联的所有成员以及向他们收取的日期和金额。如果会员没有收到费用,我需要显示零金额和空字符串。我已经尝试了CASECONVERT我可以想到的每个排列,但我似乎无法抑制默认日期。这是我试图操纵的专栏trandate。任何指针都非常感谢!这是我当前的代码,下面是当前的结果。

ALTER PROCEDURE [dbo].[usp_ApplyCharges_GetAllAssociationsDebtors]
    @tCode  int,
    @AssnKey    int
WITH RECOMPILE
AS
    SELECT
        c.pkey,
        c.lname + ', ' + c.fname as 'Name',
        c.address1,
        c.address2,
        c.assnkey,
        cs.camount as 'LastAmt',
        coalesce(c.AssmtChrgAmt, 0) as 'DefaultAmt',
        cs.trancode,
        a.name as 'AssnName' ,
        a.assmtchrgamt,
        a.latefee,
        CASE
            WHEN cs.trandate = '1900-01-01 00:00:00.000' THEN ''
            ELSE cs.trandate 
        END AS lasttrandate,
        CASE a.assmtchrgfreq
            WHEN 'A' THEN 'Annual'
            WHEN 'D' THEN 'Daily'
            WHEN 'B' THEN 'Bi-Monthly'
            WHEN 'M' THEN 'Monthly'
            WHEN 'Q' THEN 'Quarterly'
            WHEN 'S' THEN 'Semi-Annual'
            WHEN 'T' THEN 'Tri-Annual'
            ELSE 'N/A'
        END 
        AS AssessmentFrequency
    FROM 
        Cases c LEFT OUTER JOIN CaseSumm cs 
            ON c.pkey = cs.casekey
        INNER JOIN vw_CaseSumm_GetLastpKeyByTrantype v 
            ON cs.pkey = v.pkey 
        INNER JOIN assnctrl a
            ON c.assnkey = a.pkey
    WHERE
        v.trancode = @tcode and v.assnkey = @assnkey and c.active = 1
    UNION
    SELECT c2.pkey,
        c2.lname + ', ' + c2.fname as 'Name',
        c2.address1,
        c2.address2,
        c2.assnkey,
        0,
        0,
        0,
        a.name as 'AssnName',
        a.assmtchrgamt,
        a.latefee,
        '',
        CASE a.assmtchrgfreq
            WHEN 'A' THEN 'Annual'
            WHEN 'D' THEN 'Daily'
            WHEN 'B' THEN 'Bi-Monthly'
            WHEN 'M' THEN 'Monthly'
            WHEN 'Q' THEN 'Quarterly'
            WHEN 'S' THEN 'Semi-Annual'
            WHEN 'T' THEN 'Tri-Annual'
            ELSE 'N/A'
        END 
        As AssessmentFrequency
    FROM 
        Cases c2 INNER JOIN AssnCtrl a
        ON c2.assnkey = a.pkey
    WHERE c2.assnkey = @assnkey and c2.active = 1
    and c2.pkey NOT IN 
        (SELECT casekey FROM vw_CaseSumm_GetLastpKeyByTrantype WHERE assnkey = @assnkey and trancode = @tcode)
    ORDER BY Name

结果示例:

142373  Smith, John 1234 Main St.   84  0.00    0   0   Ashley Place Condominium, Inc.  333.00  0   1900-01-01 00:00:00.000 Tri-Annual

3 个答案:

答案 0 :(得分:1)

改变这个:

WHEN cs.trandate = '1900-01-01 00:00:00.000' THEN ''

进入这个

WHEN CAST(cs.trandate AS DATE) = '19000101' THEN NULL

比较浮点数时,比较日期时间总是充满错误。这只是拉出实际日期部分并进行比较,这对我的情况来说已经足够好了。

此外,由于列类型是' datetime',因此#''将被投射到日期时间,最终将成为" mindate" ...或1900-01-01。你真的想在这里使用NULL,并根据需要调整查询的其余部分来处理NULL。

答案 1 :(得分:1)

问题是CASE语句的所有可能值必须具有相同的DataType,并且将使用最严格的可能性。

您尝试在一种情况下返回空字符串,但在另一种情况下,您将返回DateTime类型。这意味着空字符串将隐式转换为DateTime,默认为1900-01-01。

如果您将日期时间值CAST为字符串,则双方都将返回一个字符串,您将能够返回一个空字符串。像这样:

CASE
    WHEN cs.trandate = '1900-01-01 00:00:00.000' THEN ''
    ELSE CONVERT(varchar(31),cs.trandate)
END AS lasttrandate,

当然,如果您可以接受为该列的输出数据类型设置字符串,那么这只是一个有用的答案。如果您需要数据类型为日期时间,则必须接受1900-01-01输出并在前端处理它。

答案 2 :(得分:0)

哇,谢谢你们!这么快就有很多很棒的回应。我尝试了所有这些,最后Tab Alleman的建议为我打了本垒打。我做了一点修改 ELSE CONVERT(varchar(10),cs.trandate,101)这样我可以作为回报的短日期。除此之外,这正是我所寻找的,并且它对你解释它的方式非常有意义,Tab。

再次感谢所有帮助过的人!