为什么SQL触发器不按顺序插入行?

时间:2012-08-13 14:41:00

标签: sql database tsql triggers

最近,我继承了一个新的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的屏幕截图,其中显示了插入到表数据中间的行。在此先感谢帮助人员。

enter image description here

2 个答案:

答案 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尽可能快地完成您的要求

希望这有帮助