英文:
The multi-part identifier could not be bound error for duplicates
问题
在我的代码中,我遇到了一个错误:
> 多部分标识符“i.Inventoryid”无法绑定。
CREATE TRIGGER trg_UpdateOrderMultiple
ON tbl_InventoryPolicy
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @OldOrderMultiple INT
DECLARE @NewOrderMultiple INT
DECLARE @Timestamp DATETIME
SELECT @OldOrderMultiple = d.ordermultiple
FROM deleted d
INNER JOIN inserted i ON i.Inventoryid = d.Inventoryid
SELECT @NewOrderMultiple = i.ordermultiple
FROM inserted i
SET @Timestamp = GETDATE()
IF NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges
WHERE Inventoryid = i.Inventoryid
AND OldOrderMultiple = @OldOrderMultiple
AND NewOrderMultiple = @NewOrderMultiple
)
BEGIN
INSERT INTO tbl_InventoryPolicyChanges
(InventoryID, OldOrderMultiple, NewOrderMultiple, Timestamp)
SELECT i.InventoryID, @OldOrderMultiple,
@NewOrderMultiple, @Timestamp
FROM inserted i
END
END
我希望避免将重复的条目插入到tbl_InventoryPolicyChanges
中。
英文:
In my code below, I am getting an error:
> The multi-part identifier "i.Inventoryid" could not be bound.
CREATE TRIGGER trg_UpdateOrderMultiple
ON tbl_InventoryPolicy
AFTER INSERT, UPDATE
AS
BEGIN
    DECLARE @OldOrderMultiple INT
    DECLARE @NewOrderMultiple INT
    DECLARE @Timestamp DATETIME
    SELECT @OldOrderMultiple = d.ordermultiple
    FROM deleted d
    INNER JOIN inserted i ON i.Inventoryid = d.Inventoryid
    SELECT @NewOrderMultiple = i.ordermultiple
    FROM inserted i
    SET @Timestamp = GETDATE()
IF NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges
WHERE Inventoryid = i.Inventoryid
AND OldOrderMultiple = @OldOrderMultiple
AND NewOrderMultiple = @NewOrderMultiple
)
BEGIN
INSERT INTO tbl_InventoryPolicyChanges
(InventoryID, OldOrderMultiple, NewOrderMultiple, Timestamp)
SELECT i.InventoryID, @OldOrderMultiple,
@NewOrderMultiple, @Timestamp
FROM inserted i
END
END
I want to avoid inserting duplicate entries into the tbl_InventoryPolicyChanges
.
答案1
得分: 2
以下是翻译的代码部分:
-
使用
Inserted
和Deleted
伪表时需要进行连接操作。 -
添加
where
子句以筛选掉不需要的更改。
INSERT INTO tbl_InventoryPolicyChanges (InventoryID, OldOrderMultiple, NewOrderMultiple, [Timestamp])
SELECT i.InventoryID, d.ordermultiple, i.ordermultiple, GETDATE()
FROM Inserted i
INNER JOIN Deleted d ON d.InventoryId = i.InventoryId
WHERE NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges
WHERE Inventoryid = i.Inventoryid
AND NewOrderMultiple = i.ordermultiple
AND OldOrderMultiple = d.ordermultiple
);
注意:您的触发器也是插入触发器,但您的逻辑不处理插入操作,因为您假设 Deleted
中会有行。如果还应处理插入操作,那么逻辑需要修改以处理 Deleted
伪表中没有行的情况。
我认为以下代码还处理了INSERT
情况,请注意LEFT JOIN
和空值比较:
INSERT INTO tbl_InventoryPolicyChanges (InventoryID, OldOrderMultiple, NewOrderMultiple, [Timestamp])
SELECT i.InventoryID, d.ordermultiple, i.ordermultiple, GETDATE()
FROM Inserted i
LEFT JOIN Deleted d ON d.InventoryId = i.InventoryId
WHERE NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges c
WHERE c.Inventoryid = i.Inventoryid
AND c.NewOrderMultiple = i.ordermultiple
AND (c.OldOrderMultiple = d.ordermultiple OR (d.ordermultiple IS NULL AND c.OldOrderMultiple IS NULL))
);
英文:
You're making the classic mistake many people make when it comes to triggers, and that is to suddenly change from regular SQL set-based operations into some sort of procedural logic. Don't do it, continue to use set-based operations as you would for any other query. I think the following converts your existing logic into set-based logic, but you'll need to validate it yourself.
-
Use joins with the
Inserted
andDeleted
pseudo tables when required -
Add a
where
clause to filter out unwanted changes
INSERT INTO tbl_InventoryPolicyChanges (InventoryID, OldOrderMultiple, NewOrderMultiple, [Timestamp])
SELECT i.InventoryID, d.ordermultiple, i.ordermultiple, GETDATE()
FROM Inserted i
INNER JOIN Deleted d on d.InventoryId = i.InventoryId
WHERE NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges
WHERE Inventoryid = i.Inventoryid
AND NewOrderMultiple = i.ordermultiple
AND OldOrderMultiple = d.ordermultiple
);
Note: Your trigger is also an insert trigger, but your logic doesn't handle insert because you assume Deleted
will have rows in it. If it should also handle inserts then the logic needs to be modified to handle no rows in the Deleted
pseudo table.
I think the following also handles the INSERT
case, note the LEFT JOIN
and the null compare:
INSERT INTO tbl_InventoryPolicyChanges (InventoryID, OldOrderMultiple, NewOrderMultiple, [Timestamp])
SELECT i.InventoryID, d.ordermultiple, i.ordermultiple, GETDATE()
FROM Inserted i
LEFT JOIN Deleted d on d.InventoryId = i.InventoryId
WHERE NOT EXISTS (
SELECT 1
FROM tbl_InventoryPolicyChanges c
WHERE c.Inventoryid = i.Inventoryid
AND c.NewOrderMultiple = i.ordermultiple
AND (c.OldOrderMultiple = d.ordermultiple OR (d.ordermultiple IS NULL AND c.OldOrderMultiple IS NULL))
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论