【问题标题】:Setting query result as default column value without using triggers将查询结果设置为默认列值而不使用触发器
【发布时间】:2019-02-03 04:19:53
【问题描述】:

我正在尝试使用默认主键(不是自动增量)创建表,类似于 oracle

fk_id varchar2(32) default sys_guid()

所以表定义是

CREATE TABLE `t_table` (
    `fk_id` TEXT DEFAULT 'select lower(hex(randomblob(16)))' UNIQUE,
    `fv_name`   TEXT,
    PRIMARY KEY(`fk_id`)
);

是的,我在插入时将此选择作为字符串值。

那么有没有不使用触发器的解决方案? 谢谢。

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    使用'select lower(hex(randomblob(16)))' 将子查询封装为字符串/文本文字,并且在指定了 UNIQUE 时只能工作一次(不需要使列 PRIMARY KEY 意味着 UNIQUE),因此任何后续插入都会失败。

    假设您希望 DEFAULT 值是 lower(hex(randomblob(16)) 的结果,那么您不能使用子查询,因为该值不会被视为 CONSTANT。

    • 就 DEFAULT 子句而言,表达式被视为 如果它不包含子查询、列或表引用,则为常量, 绑定参数,或用双引号括起来的字符串文字 单引号。SQL As Understood By SQLite - CREATE TABLE

    相反,您可以删除选择并只使用表达式,然后将其视为 CONSTANT。

    但是,要做到这一点,你需要坚持

    如果列的默认值是括号中的表达式,则 表达式对插入的每一行计算一次,结果 在新行中使用。 SQL As Understood By SQLite - CREATE TABLE

    因此你可以使用:-

    CREATE TABLE IF NOT EXISTS `t_table` (
        `fk_id` TEXT DEFAULT (lower(hex(randomblob(16)))) UNIQUE,
        `fv_name`   TEXT,
        PRIMARY KEY(`fk_id`)
    );
    

    当然,如果值不是唯一的,这种可能性越来越大,那么这将导致行不被插入。

    【讨论】:

    • 谢谢,我的单引号示例是这样格式化的,因为默认数据建模器是以这种方式插入的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多