最近,我继承了一个新的ASP网络应用程序,它只允许客户在线支付他们的未付发票。该应用程序设计不佳,没有付款历史记录表。整个付款表已被Web服务删除,该服务将付款记录传输到记录的会计系统。
我刚刚在Payments表上创建了一个简单的触发器,它只是将Payments表中的数据复制到Payment_Log表中。最初,触发器只是插入了select * on来复制数据。但是,我刚刚修改了触发器,将付款日期插入到Payment_Log表中,因为我们的一个客户遇到了一些我需要调试的问题。新触发器如下。我的问题是我注意到,使用这个新版本的触发器,行被插入到表的中间(即不在末尾)。有人可以解释为什么会这样吗?
ALTER trigger [dbo].[PaymentHistory] on [dbo].[Payments]
for insert as
Declare @InvoiceNo nvarchar(255),
@CustomerName nvarchar(255),
@PaymentAmount float,
@PaymentRefNumber nvarchar(255),
@BulkPaid bit,
@PaymentType nvarchar(255),
@PaymentDate datetime
Select @InvoiceNo = InvoiceNo,
@CustomerName = CustomerName,
@PaymentAmount = PaymentAmount,
@PaymentRefNumber = PaymentRefNumber,
@BulkPaid = BulkPaid,
@PaymentType = PaymentType
from inserted
Set @PaymentDate = GETDATE()
Insert into Payment_Log
values (@InvoiceNo, @CustomerName, @PaymentAmount, @PaymentRefNumber, @BulkPaid, @PaymentType, @PaymentDate)
下面是SQL Server Management Studio的屏幕截图,其中显示了插入到表数据中间的行。在此先感谢帮助人员。
答案 0 :(得分:5)
数据集没有订单。这意味着SELECT * FROM x
可以 每次都以不同的顺序返回结果。
时间 保证 以相同顺序返回的时间是您指定的时间ORDER BY
条款。
也就是说,有些情况会使数据正常按特定顺序返回。最明显的是聚集索引。
这让我想知道这两个表是否有主键。检查每个表上的所有索引,并至少强制执行主键。
顺便说一句,SQL Server中的触发器不是针对每一行而是针对每一批都触发。这可能意味着inserted
表可以包含多于一行。 (例如,批量插入测试数据或重新加载大批交易时。)
因此,将数据复制到变量中并不是标准做法。相反,您可以执行以下操作...
ALTER trigger [dbo].[PaymentHistory] on [dbo].[Payments]
for insert as
INSERT INTO
Payment_Log
SELECT
InvoiceNo, CustomerName, PaymentAmount, PaymentRefNumber,
BulkPaid, PaymentType, GetDate()
FROM
inserted
答案 1 :(得分:-1)
Ok这个问题与我在SQL查询中不使用order by子句时为什么行以不同的顺序返回时的答案相同。如果你要求SQL以任何方式处理行,它将以最快的方式处理它们,首先兑现行,最接近硬盘驱动器上读取头的行,最后是其余行。
换句话说:如果查询按行排序的时间比按先到先得的顺序要长10倍,那么您会感到恼火。 SQL尽可能快地完成您的要求
希望这有帮助