【问题标题】:Multi identifier error in trigger function触发函数中的多标识符错误
【发布时间】:2021-03-27 06:09:00
【问题描述】:

我有一个为插入而创建的触发器函数。我想在 StockItem 上显示更改的代码中有两个 stockTransaction 和 StokItem 并且我成功了。但现在我只需更改我的 Item 表的 BuyinPrice 列,这是更新 StokItem 表后的第三个表。

这是我的代码:

ALTER TRIGGER [dbo].[StockTransactionInserted]
ON  [dbo].[StockTransaction]
AFTER INSERT
AS 
BEGIN

SET NOCOUNT ON;

DECLARE 
@IdItem int,    
@IdStorage int,
@TransactionType char(1),
@Code char(1),
@Quantity decimal(18, 8),
@UnitPrice decimal(18, 8),
@Discount decimal(18, 8),
@FatAltDiscount decimal(18, 8),
@VAT decimal(18, 8)

SELECT 
@IdItem = IdItem, 
@IdStorage = IdStorage,
@TransactionType = TransactionType,
@Code = Code,  
@Quantity = Quantity,
@UnitPrice = UnitPrice,
@Discount = Discount,
@FatAltDiscount = FatAltDiscount,
@VAT = VAT
FROM inserted

IF NOT EXISTS (SELECT * FROM StockItem WHERE IdItem = @IdItem AND IdStorage = @IdStorage)
BEGIN
    INSERT INTO StockItem (IdItem, IdStorage, TOP_GIRIS_MIK, TOP_CIKIS_MIK)
    VALUES (@IdItem, @IdStorage, 0, 0)
END



UPDATE StockItem
SET
TOP_GIRIS_MIK = TOP_GIRIS_MIK + CASE WHEN @Code = 'G' THEN @Quantity ELSE 0 END,
TOP_GIRIS_TUT = TOP_GIRIS_TUT + CASE WHEN @Code = 'G' THEN (@UnitPrice * (1- @Discount/100)) * @Quantity ELSE 0 END,

TOP_CIKIS_MIK = TOP_CIKIS_MIK + CASE WHEN @Code = 'C' THEN @Quantity ELSE 0 END,
TOP_CIKIS_TUT = TOP_CIKIS_TUT + CASE WHEN @Code = 'C' THEN (@UnitPrice * (1- @Discount/100)) * @Quantity ELSE 0 END,

ORT_BR_FIAT = CASE WHEN ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) + @Quantity) = 0 THEN (ORT_BR_FIAT + (@UnitPrice * (1- @Discount/100))) / 2 ELSE ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) * ORT_BR_FIAT + (@Quantity * (@UnitPrice * (1- @Discount/100)))) / ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) + @Quantity) END,

SON_GIR_BR_FIAT = (CASE WHEN @UnitPrice=0 OR @TransactionType != 'A' THEN SON_GIR_BR_FIAT ELSE @UnitPrice * (1- @Discount/100) END),
SON_GIR_NET_FIAT =  (CASE WHEN @UnitPrice=0 OR @TransactionType != 'A' THEN SON_GIR_NET_FIAT ELSE (@UnitPrice * (1- @Discount/100)) + (@UnitPrice * @VAT/100) END)
WHERE IdItem = @IdItem AND IdStorage = @IdStorage

UPDATE Item
SET BuyingPrice = StockItem.SON_GIR_BR_FIAT where item_id = @IdItem
END

实际上更新 StokItem 正在工作,这不是问题,但是当我想在这里更新我的 Item 表时

UPDATE Item
SET BuyingPrice = StockItem.SON_GIR_BR_FIAT where item_id = @IdItem

显示 StockItem.SON_GIR_BR_FIAT 列的多标识符错误。

你能帮帮我吗!谢谢!

【问题讨论】:

  • inserted 可以包含 0、1 或 多个 行,具体取决于原始语句影响的行数。在后一种情况下,您的触发器无法工作。
  • UPDATE Item SET BuyingPrice = StockItem.SON_GIR_BR_FIAT where item_id = @IdItem 指的是表 (StockItem) 中未在 update 中使用的列 (SON_GIR_BR_FIAT)。您似乎期望数据库在没有from 子句的情况下找到表,然后选择合适的行来获取列值。 SQL Server 不太擅长rhabdomancy。提示:包含表的 DDL 将有助于我们理解代码。

标签: sql-server tsql triggers


【解决方案1】:

现在,它应该可以工作了! 插入的表可以包含 0、1 或多行。因此,您需要对受影响的行使用 CURSOR,以便逐行更新表 StockItem 和 Item。

ALTER TRIGGER [dbo].[StockTransactionInserted]
ON  [dbo].[StockTransaction]
AFTER INSERT
AS 
BEGIN

SET NOCOUNT ON;

DECLARE 
  @IdItem int,    
  @IdStorage int,
  @TransactionType char(1),
  @Code char(1),
  @Quantity decimal(18, 8),
  @UnitPrice decimal(18, 8),
  @Discount decimal(18, 8),
  @FatAltDiscount decimal(18, 8),
  @VAT decimal(18, 8)



DECLARE curStockTransaction CURSOR FOR   
SELECT IdItem, IdStorage, TransactionType, Code, Quantity, UnitPrice, Discount, FatAltDiscount, VAT
FROM inserted

OPEN curStockTransaction
FETCH NEXT FROM curStockTransaction INTO @IdItem, @IdStorage, @TransactionType, @Code, @Quantity, @UnitPrice, @Discount, @FatAltDiscount, @VAT
WHILE @@FETCH_STATUS = 0  
BEGIN  

  IF NOT EXISTS (SELECT * FROM StockItem WHERE IdItem = @IdItem AND IdStorage = @IdStorage)
  BEGIN
    INSERT INTO StockItem (IdItem, IdStorage, TOP_GIRIS_MIK, TOP_CIKIS_MIK)
    VALUES (@IdItem, @IdStorage, 0, 0)
  END

  UPDATE StockItem
  SET
    TOP_GIRIS_MIK = TOP_GIRIS_MIK + CASE WHEN @Code = 'G' THEN @Quantity ELSE 0 END,
    TOP_GIRIS_TUT = TOP_GIRIS_TUT + CASE WHEN @Code = 'G' THEN (@UnitPrice * (1- @Discount/100)) * @Quantity ELSE 0 END,

    TOP_CIKIS_MIK = TOP_CIKIS_MIK + CASE WHEN @Code = 'C' THEN @Quantity ELSE 0 END,
    TOP_CIKIS_TUT = TOP_CIKIS_TUT + CASE WHEN @Code = 'C' THEN (@UnitPrice * (1- @Discount/100)) * @Quantity ELSE 0 END,

    ORT_BR_FIAT = CASE WHEN ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) + @Quantity) = 0 THEN (ORT_BR_FIAT + (@UnitPrice * (1- @Discount/100))) / 2 ELSE ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) * ORT_BR_FIAT + (@Quantity * (@UnitPrice * (1- @Discount/100)))) / ((TOP_GIRIS_MIK - TOP_CIKIS_MIK) + @Quantity) END,

    SON_GIR_BR_FIAT = (CASE WHEN @UnitPrice=0 OR @TransactionType != 'A' THEN SON_GIR_BR_FIAT ELSE @UnitPrice * (1- @Discount/100) END),
    SON_GIR_NET_FIAT =  (CASE WHEN @UnitPrice=0 OR @TransactionType != 'A' THEN SON_GIR_NET_FIAT ELSE (@UnitPrice * (1- @Discount/100)) + (@UnitPrice * @VAT/100) END)
  WHERE
    IdItem = @IdItem AND IdStorage = @IdStorage

  UPDATE Item
  SET
    BuyingPrice = StockItem.SON_GIR_BR_FIAT
  FROM Item
  JOIN StockItem ON (StockItem.IdItem = Item.item_id)
  where
    item_id = @IdItem

  FETCH NEXT FROM curStockTransaction INTO @IdItem, @IdStorage, @TransactionType, @Code, @Quantity, @UnitPrice, @Discount, @FatAltDiscount, @VAT  
END   
CLOSE curStockTransaction
DEALLOCATE curStockTransaction

END

【讨论】:

  • 为什么需要光标?基于集合的解决方案难道不够而且可能更有效吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多