Gra*_*per 0 sql t-sql database 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)
Run Code Online (Sandbox Code Playgroud)
下面是SQL Server Management Studio的屏幕截图,显示了插入到表数据中间的行.在此先感谢帮助人员.

数据集没有订单.这意味着每次都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
Run Code Online (Sandbox Code Playgroud)