我正在尝试更新名为@deletedRecords
的临时表,如下所示:
使用名为log的表中的数据,如下所示:
KeyValue
表格中的log
与ID
中的@deletedRecords
相同。
@deletedRecords
中有一列用于任何特定键值的每个FieldName。
我尝试使用以下查询提取值:
UPDATE @deletedRecords
SET PatientName = (SELECT ACL.OldValue WHERE ACL.FieldName = 'CptCode'),
ChargeNotes = (SELECT ACL.OldValue WHERE ACL.FieldName = 'ChargeNotes'),
Units = (SELECT ACL.OldValue WHERE ACL.FieldName = 'Units'),
ChargeStatusID = (SELECT ACL.OldValue WHERE ACL.FieldName = 'Units')
FROM Log ACL
JOIN @deletedRecords DR ON ACL.KeyValue = DR.ID
WHERE ACL.TableName = 'BillingCharge'
AND ACL.EventType = 'DELETE'
但是,当我运行查询时,@deletedRecords
中要更新的所有列都为空。有人可以帮我解释一下我错过的东西吗?
提前致谢。
编辑:
为了回应@Yogesh Sharma的回答,我选择使用CTE方法。我希望使用CTE中的值连接到其他表并在更新期间提取它们的值。
e.g。 Log
表不包含StatusName
的旧值,但它包含ChargeStatusID
,可用于连接到包含该信息的另一个表,例如此表{{ 1}}:
因此,我将@Yogesh Sharma的代码修改为以下内容:
ChargeStatus
但是,一旦我添加了辅助连接,所有更新的值都会返回null,就像@Yogesh Sharma的建议实现之前一样。
答案 0 :(得分:0)
您的查询不起作用,因为DR中的每一行都执行了多次UPDATE,只考虑查询的最后三行中指定的条件(而不是子查询中指定的条件)。保留在表中的值是与上次执行中使用的ACL行对应的值(并且无法控制执行的顺序)。如果对于上次执行中使用的ACL行,子查询返回NULL,则会得到NULL结果。
请参阅https://docs.microsoft.com/en-us/sql/t-sql/queries/update-transact-sql主题中的示例,其中显示“如果语句包含未以这样的方式指定的FROM子句,那么UPDATE语句的结果是未定义的,即每个语句只有一个值可用更新的列出现,即UPDATE语句不确定。“。
您应该像这样重写您的查询:
UPDATE @deletedRecords
SET PatientName = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'CptCode' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
ChargeNotes = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'ChargeNotes' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
Units = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'Units' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
),
ChargeStatusID = (
SELECT ACL.OldValue FROM Log ACL
WHERE ACL.FieldName = 'Units' AND ACL.KeyValue = DR.ID
AND ACL.TableName = 'BillingCharge' AND ACL.EventType = 'DELETE'
)
FROM @deletedRecords DR
答案 1 :(得分:0)
您需要为log
表执行一些条件聚合并执行JOIN
以更新临时表@deletedRecords
记录
因此,条件方法可以通过CTE
或Subquery
WITH cte AS
(
SELECT KeyValue,
MAX(CASE WHEN FieldName = 'CptCode' THEN OldValue END) PatientName,
MAX(CASE WHEN FieldName = 'ChargeNotes' THEN OldValue END) ChargeNotes,
...
FROM Log
WHERE TableName = 'BillingCharge' AND EventType = 'DELETE'
GROUP BY KeyValue
)
UPDATE d
SET d.PatientName = c.PatientName,
...
FROM @deletedRecords d
INNER JOIN cte c ON c.KeyValue = d.ID
另一种方法是通过correlation
方法
UPDATE d
SET d.PatientName = (SELECT TOP 1 OldValue FROM Log WHERE KeyValue = d.ID AND
TableName = 'BillingCharge' AND EventType = 'DELETE' AND FieldName = 'CptCode'),
d.ChargeNotes= (SELECT TOP 1 OldValue FROM Log WHERE KeyValue = d.ID AND
TableName = 'BillingCharge' AND EventType = 'DELETE' AND FieldName = 'ChargeNotes'),
...
FROM @deletedRecords d
答案 2 :(得分:0)
如果您的更新列是NULL
,则可能是以下原因:
INNER JOIN
,因此记录可能无法通过其加入列正确加入。确保两个表在连接列上具有相同的值。WHERE
条款进行过滤,因此记录可能无法满足您的TableName
和EventType
过滤条件。确保他们之间有成功INNER JOIN
和的记录,他们拥有提供的TableName
和EventType
。NULL
。确保子查询返回非空值。使用
UPDATE DR SET
YourColumn = Value
FROM
Log ACL
JOIN @deletedRecords DR ON -...
而不是
UPDATE @deletedRecords SET
YourColumn = Value
FROM
Log ACL
JOIN @deletedRecords DR ON -...
NULL
。还要留意您的交易(可能不会被提交或回滚)。