AntDB 通过扩展 default expression 实现字段值的自动更新

本文探讨了如何通过扩展 PostgreSQL 的 Default Expression 功能来实现在 AntDB 中自动更新字段值,避免使用 TRIGGER。文章介绍了两种方案,重点讲解了方案2,包括扩展 default expression 语法,新增 ColDefaultWhen 规则和 DefaultExpr 数据结构,并验证了字段自动更新及 alter 操作的效果。

MySQLON UPDATE CURRENT_TIMESTAMP 带来的启发,AntDB 是否可以实现 UPDATE 时自动更新字段值。

方案
  • 方案1:尝试为需要自动更新的字段自动创建 TRIGGER
  • 方案2:尝试通过 DEFAULT EXPRESSION 来实现字段值的自动更新。
实现
方案1

PostgreSQL之时间戳自动更新

方案2
1. PostgreSQL 默认的 default expression 实现
CREATE TABLE ts (
    id int,
    value int DEFAULT 0,
    tt timestamp DEFAULT current_timestamp
);
2. 查看 pg_attrdef
postgres=# \d ts 
                  Table "public.ts"
 Column |            Type             |   Modifiers   
--------+-----------------------------+---------------
 id     | integer                     | 
 value  | integer                     | default 0
 tt     | timestamp without time zone | default now()

postgres=# select adrelid::regclass, adnum, pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = 'ts'::regclass ;
 adrelid | adnum | pg_get_expr 
---------+-------+-------------
 ts      |     2 | 0
 ts      |     3 | now()
(2 rows)
3. 扩展 default expression 语法

新增 ColDefaultWhen 规则,对 default expression 修饰,表示 default expression 的生效时机。

DEFAULT b_expr ColDefaultWhen
    {
        Constraint *n = makeNode(Constraint);
        n->contype = CONSTR_DEFAULT;
        n->location = @1;
        n->raw_expr = makeDefaultExpr($3, $2, @2);
        n->cooked_expr = NULL;
        $$ = (Node *)n;
    }

ColDefaultWhen:
            ON INSERT                     { $$ = DEF_ON_INSERT; }
			| ON UPDATE                   { $$ = DEF_ON_UPDATE; }
			| ON INSERT OR UPDATE         { $$ = DEF_ON_INSERT | DEF_ON_UPDATE; }
			|                             { $$ = DEF_ON_INSERT; }
        ;
4. 新增 DefaultExpr 数据结构
/*
 * Default Expression
 */
typedef struct DefaultExpr
{
    NodeTag     type;
    int16       def_when;       /* when to set default expression */
    Node       *def_expr;       /* default expression */
    int         location;       /* token location, or -1 if unknown */
} DefaultExpr;
在 SQL 数据库中,不同数据库管理系统(如 MySQL、SQL Server、Oracle)对时间戳字段自动更新支持有所不同。以下是对这些数据库实现方式的详细说明: ### MySQL 中的时间戳自动更新 MySQL 支持通过 `TIMESTAMP` 或 `DATETIME` 字段实现插入和更新操作时的自动更新功能。可以在建表语句中直接定义 `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`,以实现自动填充和更新时间戳。 例如: ```sql CREATE TABLE test_t1 ( id INT, name TEXT, last_update_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` 当插入新记录时,`last_update_date` 会自动设置为当前时间。当更新记录时,该字段自动更新为最新的时间戳[^3]。 ### SQL Server 中的时间戳自动更新MySQL 不同,SQL Server 并不直接支持字段在更新时自动更新时间戳。通常的做法是通过触发器来实现这一功能。创建触发器后,在数据更新时可以自动设置时间戳字段。 例如: ```sql CREATE TABLE tUser ( id INT PRIMARY KEY IDENTITY, name VARCHAR(20), password VARCHAR(50), updatetime DATETIME DEFAULT GETDATE() ); CREATE TRIGGER mytrigger ON tUser AFTER UPDATE, INSERT AS BEGIN UPDATE tUser SET updatetime = GETDATE() FROM tUser t INNER JOIN Inserted i ON t.id = i.id; END; ``` 在这种方式下,每次更新或插入记录时,都会触发 `updatetime` 字段的更新[^2]。 ### Oracle 中的时间戳自动更新 Oracle 数据库不支持像 MySQL 那样的自动更新时间戳字段。通常的做法是在插入或更新数据时,通过 SQL 语句显式地更新时间戳字段。例如: ```sql CREATE TABLE example_table ( id NUMBER PRIMARY KEY, create_time TIMESTAMP DEFAULT SYSTIMESTAMP, update_time TIMESTAMP ); ``` 在更新数据时,需要显式地设置 `update_time` 字段: ```sql UPDATE example_table SET update_time = SYSTIMESTAMP WHERE id = 1; ``` 这种方式虽然不如 MySQL自动更新方便,但可以通过存储过程或触发器来简化操作[^1]。 ### 相关问题 1. 如何在 MySQL 中同时实现创建时间和更新时间字段的自动填充? 2. SQL Server 中的触发器能否实现多个时间戳字段的更新? 3. Oracle 是否可以通过触发器模拟时间戳字段自动更新? 4. 不同数据库中时间戳字段的默认设置有何区别? 5. 如何测试数据库时间戳字段自动更新功能是否生效?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值