在 SQLITE 中插入后使用触发器创建组合键(YEAR+COUNT)字段

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

我有一个 Product 表,有两列:产品名称和价格,唯一键应该是由 YEAR+COUNT(10) 组合而成的值:

CREATE TABLE IF NOT EXISTS YearCounters (
    year INTEGER PRIMARY KEY,
    counter INTEGER DEFAULT 0
);

-- Product Table
CREATE TABLE IF NOT EXISTS Products (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    price REAL
);

在每次插入时,我想根据“name”和“YEARCOUNT_id”(NOT NULL)的值生成id:

INSERT INTO Products (name, price) VALUES ('Produit B', 20.15)
INSERT INTO Products (name, price) VALUES ('Produit C', 23.75);

示例:

SELECT * FROM Products;

2024000000000001|Produit B|20.15
2024000000000002|Produit C|23.75

所以,我写了一个表 TRIGGER 但没有运行。

CREATE TRIGGER IF NOT EXISTS increment_counter_and_set_product_id
BEFORE INSERT ON Products
FOR EACH ROW
BEGIN
    -- 
    UPDATE YearCounters
    SET counter = counter + 1
    WHERE year = strftime('%Y', 'now');

    --
    INSERT OR IGNORE INTO YearCounters (year, counter)
    VALUES (strftime('%Y', 'now'), 0);

    --
    SELECT counter
    INTO temp_counter
    FROM YearCounters
    WHERE year = strftime('%Y', 'now');

    -- 
    SET NEW.id = strftime('%Y', 'now') || printf('%010d', temp_counter);
END;

错误:

“INTO”附近行附近的解析错误:语法错误 从 Y 中选择计数器 INTO temp_counter 这里出错了---^

我做错了什么?

sqlite triggers key
1个回答
0
投票

也许考虑:-

INSERT INTO Products VALUES (
    (
        CAST(strftime('%Y','now') AS INTEGER) /*<<<<< Year as INTEGER*/ * 1000000000000 /* increase significance of Year */
            + 1 /* Add 1 (the next/count) */
            /* get the current year's highest current used lower significance value (the count) or 0 if no such value*/
            + coalesce(
                (SELECT max(id) % 1000000000000 FROM products WHERE substr(id,1,4) = strftime('%Y', 'now'))
                ,0
            )
    ),
'Produit B', 20.15);

这个:-

  1. 不需要触发器,因为该值是在插入时计算的
  2. 不需要 YearCounters 表,因为计数是根据当前年份的 Products 表确定的。

演示:-

DROP TABLE IF EXISTS yearcounters;
DROP TABLE IF EXISTS products;
CREATE TABLE IF NOT EXISTS YearCounters (
    year INTEGER PRIMARY KEY,
    counter INTEGER DEFAULT 0
);

-- Product Table
CREATE TABLE IF NOT EXISTS Products (
    id TEXT PRIMARY KEY,
    name TEXT NOT NULL,
    price REAL
);
INSERT INTO Products VALUES (
    (
        CAST(strftime('%Y','now') AS INTEGER) /*<<<<< Year as INTEGER*/ * 1000000000000 /* increase significance of Year */
            + 1 /* Add 1 (the next/count) */
            /* get the current year's highest current used lower significance value (the count) or 0 if no such value*/
            + coalesce(
                (SELECT max(id) % 1000000000000 FROM products WHERE substr(id,1,4) = strftime('%Y', 'now'))
                ,0
            )
    ),
'Produit B', 20.15);
INSERT INTO Products VALUES (
(
        CAST(strftime('%Y','now') AS INTEGER) /*<<<<< Year as INTEGER*/ * 1000000000000 /* increase significance of Year */
            + 1 /* Add 1 (the next/count) */
            /* get the current year's highest current used lower significance value (the count) or 0 if no such value*/
            + coalesce(
                (SELECT max(id) % 1000000000000 FROM products WHERE substr(id,1,4) = strftime('%Y', 'now'))
                ,0
            )
    ),
'Produit C', 23.75);
INSERT INTO Products VALUES (
(
        CAST(strftime('%Y','now') AS INTEGER) /*<<<<< Year as INTEGER*/ * 1000000000000 /* increase significance of Year */
            + 1 /* Add 1 (the next/count) */
            /* get the current year's highest current used lower significance value (the count) or 0 if no such value*/
            + coalesce(
                (SELECT max(id) % 1000000000000 FROM products WHERE substr(id,1,4) = strftime('%Y', 'now'))
                ,0
            )
    ),
'Produit D', 25.11);
INSERT INTO Products VALUES (
(
        CAST(strftime('%Y','now') AS INTEGER) /*<<<<< Year as INTEGER*/ * 1000000000000 /* increase significance of Year */
            + 1 /* Add 1 (the next/count) */
            /* get the current year's highest current used lower significance value (the count) or 0 if no such value*/
            + coalesce(
                (SELECT max(id) % 1000000000000 FROM products WHERE substr(id,1,4) = strftime('%Y', 'now'))
                ,0
            )
    ),
'Produit E', 26.22);
SELECT * FROM products;
DROP TABLE IF EXISTS yearcounters;
DROP TABLE IF EXISTS products;

SELECT 中的结果显示:-

enter image description here

  • 请注意,重要性乘数可能需要调整以完全适合
  • DROP(开始和结束)只是为了保持整洁的演示环境
  • 当然可以删除嵌入的注释
© www.soinside.com 2019 - 2024. All rights reserved.