2

我似乎无法追查为什么 MySQL 在尝试更新表中的列时抛出错误,如下所示。

更新查询是:

update jobitems set itemprice=itemprice/100;

错误是:

 Error Code: 1054. Unknown column 'JobID' in 'where clause'

当我从 jobitems 的触发器中删除以下内容时,更新有效。

DELIMITER $$
CREATE
DEFINER=`root`@`localhost`
TRIGGER `alacarte`.`jobitems_beforeupdate`
BEFORE UPDATE ON `alacarte`.`jobitems`
FOR EACH ROW
Begin
declare customer varchar(45);
Set @customer = (select CustomerID FROM jobs WHERE JobID=old.JobID);
If new.ItemCompleted<=>1
AND (select InvoiceStatus
    FROM 
        (Select InvoiceStatus, CustomerID
        FROM invoices
        as custinvoices
        Where CustomerID=@customer)
    as InvoiceStatus
    WHERE InvoiceStatus='Open') IS NULL
then
insert into invoices
set
CustomerID=@customer,
InvoiceBillToName=ifnull((select CustomerName FROM customers WHERE CustomerID=@customer),'-'),
InvoiceBillToAddress=etc;

当然,jobs 表有一个 JobID 和 CustomerID 列。许多其他触发器和我们的前端都使用这些列,它们可以完美地工作。

以下查询有效并返回正确的“cust-000002”。

Set @customer = (select CustomerID FROM jobs WHERE JobID='ALC-20121119-001');
select @customer;

以下查询也有效(此作业项的 ItemCompleted=0,因此它不会触发上述触发器):

update jobitems set itemprice=itemprice/100 where JobID='ALC-20121119-001';

所以,我正式坚持上述信息。请帮忙 :)。

更新:

正如预期的那样,在整个触发器中消除变量并将“@customer”替换为 (select CustomerID FROM jobs WHERE JobID=old.JobID) 会产生相同的错误。

此外,通过修改触发器,错误消失了。我以一种新的方式简单地使用了该变量,它可以工作。以下将每个作业的@customer 输出添加到测试列中,并且可以完美运行。呃!

declare customer varchar(45);
Set @customer = (select CustomerID FROM jobs WHERE JobID=old.JobID);

If new.ItemCompleted<=>1
then
update jobs set testcol=@customer where JobID=old.JobID;
end if;

更新:

为了确保我没有发疯,我将触发器复制并粘贴回来,我得到了与以前完全相同的错误消息,因此这个问题是可重现的。此外,为了彻底起见,“ItemCompleted=1”的条目无法在没有错误的情况下更新,而“ItemCompleted=0”的条目可以通过尝试通过我们的前端逐个编辑条目而在没有错误的情况下更新。我想我只是确定一下,因为我现在完全糊涂了。

4

2 回答 2

1

我会尝试通过在任何使用它的地方调用它来限定 JobID,以进行额外的消除歧义。

但我的 dba 直觉表明,实际问题可能出在其他地方——您可能有另一个触发器,该触发器被此触发器中发生的某些事情触发……也许是工作或发票表上的触发器?还是在AFTER UPDATE同一张桌子上?

打开您的常规日志,SET GLOBAL general_log = 1然后运行导致触发器错误的查询。

然后再次关闭常规日志(这样更容易找到错误,因此不要填满硬盘),然后查看常规日志,看看你遇到错误时到底发生了什么......一般除了您手动运行的最初导致触发器触发的查询之外,日志实际上应该记录从触发器内部运行的查询。

于 2012-12-31T23:44:49.243 回答
0

当你这样做时:

(select CustomerID FROM jobs WHERE JobID=old.JobID)

JobID,没有前缀,是您说您拥有的工作表中的列。现在old.JobIdjobitems.JobID,因为 old 引用了在触发它的更新中使用的表。

检查您与jobitems匹配的列名是否正是jobID

于 2012-12-31T20:12:27.140 回答