【发布时间】:2016-04-15 15:12:31
【问题描述】:
我有一个包含以下列的表格:
id、xml、receivedDate、handledDateTime、orderNumber
id、receivedDate 和 processed 都有默认值。
存储在 xml 列中的 XML 如下所示:
<v1:OrderStatus xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://xmlns.dell.com/Services/DMT/OrderStatus/V1">
<v1:BusinessUnitId>11</v1:BusinessUnitId>
<v1:OrderNumber>964806604</v1:OrderNumber>
<v1:OrderStatusCode>RDD</v1:OrderStatusCode>
<v1:StatusDateTime>2016-04-12T01:16:28</v1:StatusDateTime>
<v1:RDD_Date>2016-04-19T00:00:00</v1:RDD_Date>
</v1:OrderStatus>
当 XML 被插入到表中时,我需要获取 OrderNumber 的值并将其设置在 orderNumber 列中。我开发了一个触发器来尝试完成此操作,但不是仅在新插入的行中设置值,而是为表中的所有行设置值。
我的触发器看起来像:
declare @ordernumber varchar(50)
select @ordernumber=(select xml.value('(//*:OrderNumber)[1]', 'varchar(max)') as orderNumber from inserted)
Update [dbo].[dell.des.OCIMessages]
set orderNumber=@ordernumber
END
我在另一个表上有另一个触发器,它连接这两个表之间的 orderNumber 值,我在插入/更新后使用这个另一个触发器来查找具有匹配 orderNumber 和处理 = 0 的行,然后设置处理 = 1并设置 processesDateTime 字段。
不幸的是,由于我的第一个触发器更新所有行以使用相同的订单号值,我的第二个触发器无意中总是更新所有行,因为订单号值对于我的表中的每一行都是相同的。
有人可以解释一下我的触发器出了什么问题,以便它只更新插入的行吗?
顺便说一句,我一次只插入一行,所以我不必担心我的触发器必须处理多条记录。
谢谢!
【问题讨论】:
-
我强烈反对您只能指望插入单行。从应用程序来看这可能是正确的,但是什么数据维护和诸如此类的事情呢?你应该让你的触发器集基于。至于手头的实际问题,您有两个问题。首先,您的更新语句没有 where 子句,因此它将更新整个表。其次,如果您尝试“拦截”并更改插入的值,则应使用触发器而不是触发器并在触发器中创建插入。
-
这是一个很好的起点。 spaghettidba.com/2015/04/24/…
-
最终将我的触发器更改为:声明@ordernumber varchar(50) select @ordernumber=(select xml.value('(//*:OrderNumber)[1]', 'varchar(max )') as orderNumber from inserted) Update [dbo].[dell.des.OCIMessages] set orderNumber=@ordernumber from [dell.des.OCIMessages] 内部连接插入 [dell.des.OCIMessages].id=inserted.id END 这似乎有效。我喜欢介绍的其他一些方法。所以我明白了,我目前的实现有什么问题?
-
好吧,如果它对你有用,那就没有错。但是:每当您尝试一次插入多个时,这都会中断。迟早会发生这种情况...如果您的 XML 更改,计算列(可以定义为
persistent以避免重复计算)甚至会做出反应。Instead Of Trigger让您完全控制插入过程。这两种方法都更好、更安全。 -
还有一个提示,更多的是我自己关心的 :-) Please read this: someone-answers.
标签: sql sql-server xml triggers xquery