SQL SELECT中的零错误除法

Sha*_*die 0 t-sql sql-server

SELECT 
   *
FROM 
   RM_Sales_Union
WHERE
   DOCDATE >= 'September 1, 2011'
   AND DOCDATE < 'October 1, 2011'  
   AND CUSTNMBR = '2186020'
Run Code Online (Sandbox Code Playgroud)

该查询导致错误:

Msg 8134,Level 16,State 1,Line 1
遇到零误差.

如果运行如图所示.

排除最后一行AND CUSTNMBR = '2186020'允许查询完成.

CUSTNMBR是一个char(21)领域.除以零让我感到困惑.

解决这个问题的"正确"方法是什么?

RM_Sales_Union是一个联合查询视图:

SELECT ACTNUMBR_1,
       ACTNUMBR_2,
       ACTNUMBR_3,
       ORSLSAMT,
       CUSTCLAS,
       CUSTNAME,
       CUSTNMBR,
       SLPRSNID,
       DOCABREV,
       CSPORNBR,
       CURNCYID,
       DOCDATE,
       DOCNUMBR,
       GLPOSTDT,
       SLSAMNT,
       VOIDSTTS,
       SLPRSNFN,
       SPRSNSLN,
       DocOrigin,
       ORFRTAMT,
       FRTAMNT,
       COMPRCNT,
       TRDISAMT,
       ORTDISAM,
       ORMISCAMT,
       ORTAXAMT,
       ORCTRXAM
FROM   dbo.RM_Sales_Hist
UNION
SELECT ACTNUMBR_1,
       ACTNUMBR_2,
       ACTNUMBR_3,
       ORSLSAMT,
       CUSTCLAS,
       CUSTNAME,
       CUSTNMBR,
       SLPRSNID,
       DOCABREV,
       CSPORNBR,
       CURNCYID,
       DOCDATE,
       DOCNUMBR,
       GLPOSTDT,
       SLSAMNT,
       VOIDSTTS,
       SLPRSNFN,
       SPRSNSLN,
       DocOrigin,
       ORFRTAMT,
       FRTAMNT,
       COMPRCNT,
       TRDISAMT,
       ORTDISAM,
       ORMISCAMT,
       ORTAXAMT,
       ORCTRXAM
FROM   dbo.RM_Sales_Open  
Run Code Online (Sandbox Code Playgroud)

RM_Sales_Hist和RM_Sales_Open是定义如下的视图:

--RM_Sales_Hist
SELECT dbo.GL_Sales_Accounts.ACTNUMBR_1,
       dbo.GL_Sales_Accounts.ACTNUMBR_2,
       dbo.GL_Sales_Accounts.ACTNUMBR_3,
       ISNULL(dbo.MC020102.ORSLSAMT, dbo.RM30101.SLSAMNT) AS ORSLSAMT,
       dbo.RM00101.CUSTCLAS,
       dbo.RM00101.CUSTNAME,
       dbo.RM00101.CUSTNMBR,
       dbo.RM00101.SLPRSNID,
       dbo.RM40401.DOCABREV,
       dbo.RM30101.CSPORNBR,
       dbo.RM30101.CURNCYID,
       dbo.RM30101.DOCDATE,
       dbo.RM30101.DOCNUMBR,
       dbo.RM30101.GLPOSTDT,
       dbo.RM30101.SLSAMNT,
       dbo.RM30101.VOIDSTTS,
       dbo.RM00301.SLPRSNFN,
       dbo.RM00301.SPRSNSLN,
       'HIST'                                             AS DocOrigin,
       ISNULL(dbo.MC020102.ORFRTAMT, dbo.RM30101.FRTAMNT) AS ORFRTAMT,
       dbo.RM30101.FRTAMNT,
       dbo.RM00301.COMPRCNT,
       dbo.RM30101.TRDISAMT,
       ISNULL(dbo.MC020102.ORTDISAM, 0)                   AS ORTDISAM,
       ISNULL(dbo.MC020102.ORMISCAMT, 0)                  AS ORMISCAMT,
       ISNULL(dbo.MC020102.ORTAXAMT, 0)                   AS ORTAXAMT,
       ISNULL(dbo.MC020102.ORCTRXAM, 0)                   AS ORCTRXAM,
       dbo.RM00101.STATE
FROM   dbo.GL_Sales_Accounts
       INNER JOIN dbo.RM30301
         ON dbo.GL_Sales_Accounts.DSTINDX = dbo.RM30301.DSTINDX
       INNER JOIN dbo.RM30101
         ON dbo.RM30301.CUSTNMBR = dbo.RM30101.CUSTNMBR
            AND dbo.RM30301.DOCNUMBR = dbo.RM30101.DOCNUMBR
       INNER JOIN dbo.RM00101
         ON dbo.RM30101.CUSTNMBR = dbo.RM00101.CUSTNMBR
       INNER JOIN dbo.RM40401
         ON dbo.RM30101.RMDTYPAL = dbo.RM40401.RMDTYPAL
       INNER JOIN dbo.RM00301
         ON dbo.RM00101.SLPRSNID = dbo.RM00301.SLPRSNID
       LEFT OUTER JOIN dbo.MC020102
         ON dbo.RM30301.DOCNUMBR = dbo.MC020102.DOCNUMBR
WHERE  ( CAST(dbo.RM30301.DOCNUMBR AS VARCHAR(21)) NOT IN (SELECT
         CAST(
                                                                 DOCNUMBR AS
                                                                 VARCHAR(21)) AS
         Expr1
                                                           FROM
                  dbo.Invoices_With_Display_Discounts) )

--RM_Sales_Open
SELECT dbo.GL_Sales_Accounts.ACTNUMBR_1,
       dbo.GL_Sales_Accounts.ACTNUMBR_2,
       dbo.GL_Sales_Accounts.ACTNUMBR_3,
       ISNULL(dbo.MC020102.ORSLSAMT, 0)  AS ORSLSAMT,
       dbo.RM00101.CUSTCLAS,
       dbo.RM00101.CUSTNAME,
       dbo.RM00101.CUSTNMBR,
       dbo.RM00101.SLPRSNID,
       dbo.RM40401.DOCABREV,
       dbo.RM20101.CSPORNBR,
       dbo.RM20101.CURNCYID,
       dbo.RM20101.DOCDATE,
       dbo.RM20101.DOCNUMBR,
       dbo.RM20101.GLPOSTDT,
       dbo.RM20101.SLSAMNT,
       dbo.RM20101.VOIDSTTS,
       dbo.RM00301.SLPRSNFN,
       dbo.RM00301.SPRSNSLN,
       'OPEN'                            AS DocOrigin,
       ISNULL(dbo.MC020102.ORFRTAMT, 0)  AS ORFRTAMT,
       dbo.RM20101.FRTAMNT,
       dbo.RM00301.COMPRCNT,
       dbo.RM20101.TRDISAMT,
       ISNULL(dbo.MC020102.ORTDISAM, 0)  AS ORTDISAM,
       ISNULL(dbo.MC020102.ORMISCAMT, 0) AS ORMISCAMT,
       ISNULL(dbo.MC020102.ORTAXAMT, 0)  AS ORTAXAMT,
       ISNULL(dbo.MC020102.ORCTRXAM, 0)  AS ORCTRXAM,
       dbo.RM00101.STATE
FROM   dbo.GL_Sales_Accounts
       INNER JOIN dbo.RM10101
         ON dbo.GL_Sales_Accounts.DSTINDX = dbo.RM10101.DSTINDX
       INNER JOIN dbo.RM20101
         ON dbo.RM10101.CUSTNMBR = dbo.RM20101.CUSTNMBR
            AND dbo.RM10101.DOCNUMBR = dbo.RM20101.DOCNUMBR
       INNER JOIN dbo.RM00101
         ON dbo.RM20101.CUSTNMBR = dbo.RM00101.CUSTNMBR
       INNER JOIN dbo.RM40401
         ON dbo.RM20101.RMDTYPAL = dbo.RM40401.RMDTYPAL
       INNER JOIN dbo.RM00301
         ON dbo.RM00101.SLPRSNID = dbo.RM00301.SLPRSNID
       LEFT OUTER JOIN dbo.MC020102
         ON dbo.RM10101.DOCNUMBR = dbo.MC020102.DOCNUMBR
WHERE  ( CAST(dbo.RM20101.DOCNUMBR AS VARCHAR(21)) NOT IN (SELECT
         CAST(
                                                                 DOCNUMBR AS
                                                                 varchar(21)) AS
         Expr1
                                                           FROM
                  dbo.Invoices_With_Display_Discounts) )  
Run Code Online (Sandbox Code Playgroud)

gbn*_*gbn 5

我猜RM_Sales_Union是一个包含分区的视图.过滤器只是改变COUNT或SUM之类的值来给出零,并且它被用作除数

将其更改为用于something/NULLIF(..., 0)使表达式为NULL.或者ISNULL(something/NULLIF(..., 0), 0)改为获取NULL