SQL存储过程问题-十进制值转换问题
我在SQL Server存储过程中遇到了一个非常奇怪的问题 我有两个数据库。其中一个包含我的计费系统的数据库。另一个是具有汇总数据的报告系统。在这个数据库中有一个包含汇总作业信息的表。创建此数据时,其中一个字段BilledToDate为空。我编写了一个存储过程,它创建了一个游标,该游标遍历该表并获取所有作业编号。然后,我检查每个作业编号,并对账单数据库运行查询,以获得已针对作业收取的账单总额。一旦我有了这个总数,我就用这个值更新BilledToDate列 问题是,在运行存储过程之后,有些结果是正确的,有些则不是。对于为什么一个是正确的,而下一个是错误的,似乎没有任何合乎逻辑的解释。我在存储过程中放入了一些print语句,所有的值都是正确的。例如,对于一条记录,正确的总和为99218.25,但更新将值14700.70放入BilledToDate字段。我向表中添加了一个varchar列,并填充了该字段。他们都是对的。这让我相信这是一个铸造问题,但我检查了我的数据类型,并再次检查了它们,它们看起来都是正确的。我在这件事上发疯(剩下的很少了) 下面是我的存储过程。InvoiceAmt字段是invchead表中的一个十进制(16,2),我在整个过程中保持了它的一致性,所以我不理解为什么会发生这种情况SQL存储过程问题-十进制值转换问题,sql,sql-server,Sql,Sql Server,我在SQL Server存储过程中遇到了一个非常奇怪的问题 我有两个数据库。其中一个包含我的计费系统的数据库。另一个是具有汇总数据的报告系统。在这个数据库中有一个包含汇总作业信息的表。创建此数据时,其中一个字段BilledToDate为空。我编写了一个存储过程,它创建了一个游标,该游标遍历该表并获取所有作业编号。然后,我检查每个作业编号,并对账单数据库运行查询,以获得已针对作业收取的账单总额。一旦我有了这个总数,我就用这个值更新BilledToDate列 问题是,在运行存储过程之后,有些结果是正
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, SUM(ISNULL(invoiceamt,0)))
*注意在这两种情况下都使用ISNULL(),这一点很重要,因为不能对null进行数学运算
不需要使用光标。只需在一个update语句中将两个表连接在一起,并将其作为一个批处理
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
这和你想做的一样吗
WITH inv AS
(
SELECT shortchar01,
CONVERT(MONEY, CASE WHEN SUM(invoiceamt) > 0 THEN
SUM(InvoiceAmt)
ELSE 0 END) AS BilledToDate
FROM mfgsys803.dbo.invchead
GROUP BY shortchar01
)
UPDATE StructuralOpenBilling
SET BilledToDate = inv.BilledToDate,
BilledCheck = CONVERT(VARCHAR(50), inv.BilledToDate)
FROM StructuralOpenBilling sob
JOIN inv ON inv.shortchar01 = RTRIM(sob.JobID)
您能否提供SP使用的表结构?另外,您是否尝试过更小的数据集来暴露问题?您能提供一些示例数据吗?为什么BilledToDate使用货币数据类型:选择@BilledToDate=CONVERT(money,当SUM(invoiceamt)>0时为CASE,然后选择SUM(invoiceamt)或0 END,当它最初定义为十进制(16,2)时?为什么给billedtoDATE分配一个十进制值呢?我想他的意思是“billedtoDATE是指“到目前为止,您已经收到多少账单了”(即“到目前为止”)。我从来没有看到您的建议,所以我想让它起作用。执行此语句时,会出现“无效列名'shortchar01'”错误。我查看了查询,不知道为什么它不识别I.shortchar01。有什么想法吗?你的两个
SELECT@biledtodate
版本不一样。首先是检查底片。谢谢@Martin。是的,你是对的,我错了。如果@user412421只想对正发票求和(与之相反——退款等),那么他们需要使用第一个。@user412421——我修正了它——对此表示抱歉。
WITH inv AS
(
SELECT shortchar01,
CONVERT(MONEY, CASE WHEN SUM(invoiceamt) > 0 THEN
SUM(InvoiceAmt)
ELSE 0 END) AS BilledToDate
FROM mfgsys803.dbo.invchead
GROUP BY shortchar01
)
UPDATE StructuralOpenBilling
SET BilledToDate = inv.BilledToDate,
BilledCheck = CONVERT(VARCHAR(50), inv.BilledToDate)
FROM StructuralOpenBilling sob
JOIN inv ON inv.shortchar01 = RTRIM(sob.JobID)