AFTER INSERT 触发器出现“不明确的列名称”错误

问题描述 投票:0回答:1

在 DBeaver 版本 23.3.4.202402060628 中,我有以下 SQLite3 代码(用于工厂中的高速注塑零件和包装跟踪机):

--------------------------------------------------------------------------------
-- SQLite TABLE
DROP TABLE IF EXISTS pkgdata;

CREATE TABLE pkgdata (
    DateTime TEXT, -- source format = "DD.MM.YYYY HH:mm:ss.sss"
    Weight REAL,
    Height REAL,
    Boxes INT,
    Parts INT,
    Spread REAL GENERATED ALWAYS AS (Weight - Height) STORED,
    gen_pkg_year  INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 7, 4)) STORED,
    gen_pkg_month INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 4, 2)) STORED,
    gen_pkg_day   INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 1, 2)) STORED,
    gen_pkg_wkday INT GENERATED ALWAYS AS (strftime('%w',DateTime)) STORED,
    gen_pkg_per   TEXT GENERATED ALWAYS AS (strftime('%p',DateTime)) STORED,
    gen_pkg_hr    INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 12, 2)) STORED,
    gen_pkg_min   INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 15, 2)) STORED,
    gen_pkg_sec   INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 18, 2)) STORED,
    gen_pkg_ms    INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 21, 3)) STORED,
    gen_ISODate TEXT GENERATED ALWAYS AS (
        printf('%04d-%02d-%02d %02d:%02d:%02d.%03d',
        gen_pkg_year, gen_pkg_month, gen_pkg_day,
        gen_pkg_hr, gen_pkg_min, gen_pkg_sec, gen_pkg_ms)
    ) STORED,
    prev_Weight REAL,
    prev_Height REAL,
    Weight_diff REAL,
    Height_diff REAL,
    Weight_move TEXT,
    Height_move TEXT,
    gap      TEXT
);

--------------------------------------------------------------------------------
-- SQLite INDICES - created one line at a time
CREATE INDEX pkg_idx_ymd ON pkgdata (gen_pkg_year, gen_pkg_month, gen_pkg_day);
CREATE INDEX pkg_idx_mon ON pkgdata (gen_pkg_month);
CREATE INDEX pkg_idx_dom ON pkgdata (gen_pkg_day);
CREATE INDEX pkg_idx_dow ON pkgdata (gen_pkg_wkday);
CREATE INDEX pkg_idx_per ON pkgdata (gen_pkg_per);
CREATE INDEX pkg_idx_hr  ON pkgdata (gen_pkg_hr);
CREATE INDEX pkg_idx_min ON pkgdata (gen_pkg_min);

--------------------------------------------------------------------------------
-- SQLite TRIGGER
DROP TRIGGER IF EXISTS pkg_tr_fill_calculated_columns;

CREATE TRIGGER pkg_tr_fill_calculated_columns
    AFTER INSERT ON pkgdata
BEGIN
    UPDATE pkgdata
        SET prev_Weight = previous.Weight,
            prev_Height = previous.Height,
            Weight_diff = NEW.Weight - previous.Weight,
            Height_diff = NEW.Height - previous.Height,
            Weight_move = CASE
                WHEN Weight > prev_Weight THEN 'H'
                WHEN Weight = prev_Weight THEN 'S'
                WHEN Weight < prev_Weight THEN 'L'
            END,
            Height_move = CASE
                WHEN Height > prev_Height THEN 'H'
                WHEN Height = prev_Height THEN 'S'
                WHEN Height < prev_Height THEN 'L'
            END,
            gap = CASE
                WHEN Height > prev_Weight THEN 'U'
                WHEN Weight < prev_Height THEN 'D'
                ELSE ''
            END
    FROM (SELECT * FROM pkgdata
        ORDER BY gen_ISODate DESC
        LIMIT 1, 1) AS previous -- get the previous row
    WHERE pkgdata.DateTime = NEW.DateTime;
END;

--------------------------------------------------------------------------------
-- SQLite INSERT DATA
INSERT INTO pkgdata (
    DateTime, -- TEXT
    Weight,   -- REAL
    Height,   -- REAL
    Boxes,    -- INT
    Parts)    -- INT
VALUES
    ('01.01.2010 00:00:00.817',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:01.157',0.89753,0.89728,0,0),
    ('01.01.2010 00:00:01.457',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:01.737',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:02.417',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:02.747',0.8975,0.8973,0,0),
    ('01.01.2010 00:00:06.295',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:06.566',0.89758,0.89723,0,0),
    ('01.01.2010 00:00:06.866',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:09.985',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:10.325',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:11.055',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:12.385',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:12.604',0.8975,0.8973,0,0),
    ('01.01.2010 00:00:12.884',0.89755,0.89725,0,0),
    ('01.01.2010 00:00:13.114',0.89758,0.89723,0,0),
    ('01.01.2010 00:00:15.283',0.89758,0.89723,0,0),
    ('01.01.2010 00:00:15.514',0.8975,0.8973,0,0),
    ('01.01.2010 00:00:15.684',0.8975,0.8973,0,0),
    ('01.01.2010 00:00:17.083',0.8975,0.8973,0,0),
    ('01.01.2010 00:00:17.693',0.8975,0.8973,0,0)
    returning *;

我有工作代码,但现在当我到达

INSERT
语句时出现错误(DBeaver接受每个块):

SQL 错误 1:[SQLITE_ERROR] SQL 错误或丢失数据库(不明确的列名称:Weight)

只有一张表,其中有一列名为

Weight
。从这篇文章开始,我认为内存中仍然有一些东西,所以我断开了所有其他数据库的连接,并删除了这个数据库中的所有表,然后从头开始。我尝试通过添加表名来使用完全限定名称:

INSERT INTO pkgdata (
    pkgdata.DateTime, -- TEXT
    pkgdata.Weight,   -- REAL
    pkgdata.Height,   -- REAL
    pkgdata.Boxes,    -- INT
    pkgdata.Parts)    -- INT
VALUES
...

但是它会在句点上抛出语法错误。

sql sqlite triggers sql-insert
1个回答
0
投票

“... 但是现在当我到达

INSERT
语句 ...”

时出现错误

AFTER INSERT

 事件中的 
UPDATE
触发器无法区分三个
WHEN
表达式中每个
CASE
子句的所有列名称上的插入(触发事件之前)和更新(触发事件之后)关联行,因此“列名不明确”错误。

DBeaver 接受每个块

发出

CREATE TRIGGER
时不会导致语法错误,因为
CASE
表达式本身
是有效的(仅在触发事件的上下文中变得不明确)。

我尝试通过在表名称前面添加完全限定名称:...但随后它会在句点上引发语法错误。

这是预料之中的

在每个触发器

NEW.column-name
事件的
OLD.column-name
表达式中的每个
WHEN
子句上,在列名称前面添加预期的触发事件之前或之后引用(
UPDATE
CASE
)。另外,请考虑在 CASE 表达式的
WHEN
子句中使用
虚拟列
(或生成它们的计算),而不是单独使用
SET
计算依赖于它的同一触发器
UPDATE
事件中的数据(在此过程中冗余重复)。

© www.soinside.com 2019 - 2024. All rights reserved.