Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如果DML语句的目标表'receive'包含OUTPUT子句而不包含INTO子句,则该语句不能有任何已启用的触发器_Sql Server - Fatal编程技术网

Sql server 如果DML语句的目标表'receive'包含OUTPUT子句而不包含INTO子句,则该语句不能有任何已启用的触发器

Sql server 如果DML语句的目标表'receive'包含OUTPUT子句而不包含INTO子句,则该语句不能有任何已启用的触发器,sql-server,Sql Server,我有一个名为INVOICE的表,它存储关于订单的账单信息,该表中的一列是名为paid的列,这是一种bit类型。如其名称所示,此列指示是否支付特定订单/订单账单 我有另一个名为receive的表,该表存储有关特定发票的任何付款过程的信息 因此,每次用户为指定发票支付金额时,都会创建一个新的收据记录 现在我要做的是创建一个触发器来更新发票表中的paid列,并将其设置为1。如果属于发票的收据总数等于发票表中的应付金额,则应触发此更新过程 换句话说,如果发票到期金额=100$ 用户支付了50英镑$ 后来

我有一个名为INVOICE的表,它存储关于订单的账单信息,该表中的一列是名为paid的列,这是一种bit类型。如其名称所示,此列指示是否支付特定订单/订单账单

我有另一个名为receive的表,该表存储有关特定发票的任何付款过程的信息

因此,每次用户为指定发票支付金额时,都会创建一个新的收据记录

现在我要做的是创建一个触发器来更新发票表中的paid列,并将其设置为1。如果属于发票的收据总数等于发票表中的应付金额,则应触发此更新过程

换句话说,如果发票到期金额=100$ 用户支付了50英镑$ 后来,他付了另外50英镑$ 发票表中的“已付款”列应设置为1,因为总付款等于发票到期金额

这是我为实现上述目标而创建的触发器

CREATE TRIGGER tg_invoice_payment ON RECEIPT
AFTER INSERT
AS
BEGIN
UPDATE INVOICE
SET paid = 1 
WHERE INVOICE.invoice_id = (SELECT inserted.invoice_id FROM inserted)
AND (SELECT SUM(RECEIPT.amount_paid) 
FROM RECEIPT 
JOIN inserted ON RECEIPT.receipt_id = inserted.receipt_id 
WHERE RECEIPT.invoice_id = inserted.invoice_id) = (SELECT INVOICE.amount_due 
FROM INVOICE 
JOIN inserted ON INVOICE.invoice_id = inserted.invoice_id 
WHERE INVOICE.invoice_id = inserted.invoice_id)
END;
它已成功编译,但在运行时出现以下错误:

如果DML语句的目标表“receive”包含OUTPUT子句而不包含INTO子句,则该语句不能有任何已启用的触发器


我个人认为你应该更新触发器范围之外的付费状态。如果执行插入收据,则可以执行更新发票。。。当然,在这之后的一次交易中。这样做更干净、更可预测

至于你得到的错误,根据你给我们的信息,很难说是什么原因造成的。可能该触发器正在触发其他触发器,从而产生您所获得的错误?您提供的语句没有输出语句

在任何情况下,您提供的语句都没有像Damien指出的那样正确编写,因为插入的表可能有多行。这是一次重写,以至少更正该部分:

CREATE TRIGGER tg_invoice_payment ON RECEIPT
AFTER INSERT
AS
BEGIN
    UPDATE
        INVOICE
    SET 
        paid = 1
    FROM
        inserted AS ins
        INNER JOIN INVOICE AS inv ON
            inv.invoice_id=ins.invoice_id
    WHERE
        inv.amount_due=(
            SELECT 
                SUM(r.amount_paid) 
            FROM 
                RECEIPT AS r
            WHERE
                r.receipt_id=ins.invoice_id
        );
END;

但正如我前面提到的,你可能不是通过触发器来做这件事的。在任何插入/更新之后立即从程序中执行此语句。或者,编写一个用于插入收据的存储过程,并在插入后立即执行UPDATE语句。

问题出在您没有向我们展示的一段代码中,该代码正在执行插入。。。输出…,并且,正如错误消息所明确指出的,IMO,它没有使用INTO。此外,您的触发器已损坏。INVOICE.INVOICE\u id=选择inserted.INVOICE\u id FROM inserted将在inserted包含多行时产生错误。收据表是否有自动递增的标识列?请参考:非常感谢,我对SQL语法不太熟悉,但我从错误中了解到,如果有输出语句,则必须有INTO子句,但实际上我的代码和您的代码不包含任何输出语句。我不知道我是否理解正确,再次感谢@TT@AliAlhamaly此语句中没有OUTPUT子句。这是你的线索,你应该在别处寻找问题的原因。德国劳埃德船级社!我想我已经找到了问题的原因,RECEIPT表中的id列是一个自动递增的identity列。在google上搜索时,我发现包含update语句的已启用触发器无法在包含此类id列的表上触发,我指的是自动递增的标识表。所以我现在需要解决这个问题来绕过这个错误。但仍然不确定这是否是真正的原因,这似乎与你的案件有关。您正在插入/更新收据,insert语句显然有一个OUTPUT子句。要么你在。。。或重写语句,使其不包含OUTPUT子句。