SQL存储过程问题 – 十进制值转换问题

我在SQL Server存储过程中遇到了一个非常奇怪的问题.

我有两个数据库.一个包含我的计费系统的数据库.另一种是具有汇总数据的报告系统.在此数据库中,有一个包含汇总作业信息的表.创建此数据时,其中一个字段BilledToDate为null.我编写了一个存储过程,创建一个遍历此表的游标并获取所有作业号.然后,我查看每个工作号码并对计费数据库运行查询,以获得已根据工作收取的计费总额.获得此总数后,我将使用此值更新BilledToDate列.

问题是在运行存储过程后,某些结果是正确的,而有些则不是.似乎没有任何合理的解释为什么一个是正确的而下一个是不对的.我在存储过程中放了一些print语句,所有值都是正确的.例如,对于一条记录,正确的总和为99,218.25,但更新将值14,700.70放入BilledToDate字段.我在表中添加了一个varchar列并填充了该字段.他们都是正确的.这让我相信它是一个投射问题,但我检查并仔细检查了我的数据类型,它们看起来都是正确的.我正在把头发拉出来(剩下的东西).

我的存储过程如下. InvoiceAmt字段是invchead表中的十进制(16,2),我在整个过程中保持一致,所以我不承认为什么会发生这种情况.

ALTER PROCEDURE [dbo].[sp_CalculateBilledToDate] 
AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;

    DECLARE @JobID varchar(10)
    DECLARE @RecordID int
    DECLARE @BilledToDate decimal(16,2)

    DECLARE c1 CURSOR FOR
    SELECT JobID, RecordID
    FROM StructuralOpenBilling

    OPEN c1

    FETCH NEXT FROM c1
    INTO @JobID, @RecordID

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @BilledToDate = CONVERT(money, CASE WHEN SUM(invoiceamt) > 0 THEN SUM(InvoiceAmt) ELSE 0 END)
        FROM mfgsys803.dbo.invchead
        WHERE shortchar01 = RTRIM(@JobID)

        PRINT 'Record ID: ' + CONVERT(varchar(10), @RecordID) + '  JobID: ' + RTRIM(CONVERT(varchar(10), @JobID)) + '  Billed: ' + CONVERT(varchar(10), @BilledToDate)

        UPDATE StructuralOpenBilling
        SET BilledToDate = @BilledToDate, BilledCheck = CONVERT(varchar(50), @BilledToDate)
        WHERE RecordID = @RecordID

        PRINT 'Record ID: ' + CONVERT(varchar(10), @RecordID) + '  JobID: ' + RTRIM(CONVERT(varchar(10), @JobID)) + '  Billed: ' + CONVERT(varchar(10), @BilledToDate)

        FETCH NEXT FROM c1
        INTO @JobID, @RecordID
    END

    CLOSE c1
    DEALLOCATE c1

END

任何想法,将不胜感激.

谢谢.

约翰

最佳答案 我注意到你可能会看到的一些事情.顺便说一句 – 你真的过分思考了这一点 – 这里也有一些想法.

SELECT @BilledToDate = CONVERT(money, CASE WHEN SUM(ISNULL(invoiceamt,0)) > 0 THEN SUM(ISNULL(InvoiceAmt,0)) ELSE 0 END)

是相同的

SELECT @BilledToDate = CONVERT(money, SUM(ISNULL(invoiceamt,0)))

*注意在两者中使用ISNULL() – 这很重要,因为你不能对空值进行数学运算.

没必要使用游标.只需在一个更新语句中将两个表连接在一起,即可批量处理.

UPDATE StructuralOpenBilling
SET S.BilledToDate = I.BilledToDate
FROM
      StructuralOpenBilling S
   INNER JOIN
      (SELECT shortchar01, CONVERT(money, SUM(ISNULL(invoiceamt,0))) as BilledToDate
        FROM mfgsys803.dbo.invchead) I
   ON
      S.JobID = I.shortchar01
点赞