创建表列时如何正确使用 ON UPDATE CURRENT_TIMESTAMP?
Posted
技术标签:
【中文标题】创建表列时如何正确使用 ON UPDATE CURRENT_TIMESTAMP?【英文标题】:How do I properly use ON UPDATE CURRENT_TIMESTAMP when creating table column? 【发布时间】:2020-05-12 22:27:28 【问题描述】:我是 SQL 的新手,我看到在创建包含列的表时,只要更新列(这正是我想要的),我就可以自动将列更新为当前时间戳,具体如下:
CREATE TABLE IF NOT EXISTS Foo (
Symbol CHAR(5),
LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
所以,根据我的理解,当我在这个表中插入一个符号时,例如'Baz',它应该在表中创建以下条目:
|---------------------|------------------|
| Symbol | LastUpdated |
|---------------------|------------------|
| Baz | <current time> |
|---------------------|------------------|
如果我将符号从“Baz”更新为“Qux”,则该行的 LastUpdated 列应更改为新的当前日期时间。但是,当我使用 sqlite3 模块在 python 中运行该查询时,出现以下错误:sqlite3.OperationalError: near "ON": syntax error
。这是代码在 Python 中的样子:
self.__conn = sqlite3.connect(database_path)
self.__cursor = self.__conn.cursor()
self.__cursor.execute("""CREATE TABLE IF NOT EXISTS EQData (
Symbol CHAR(5),
LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP)""")
我尝试过稍微弄乱该列定义,我发现如果我删除 ON UPDATE CURRENT_TIMESTAMP
部分,所以它只是 LastUpdated DATETIME DEFAULT CURRENT_TIMESTAMP
查询将执行得很好,但问题是我仍然希望它每当更新该行时自动更新其 LastUpdated 列。我看到here 我可以使用某种代码,该代码看起来像是触发了一个事件,当我的行更新时将更新列,但我不确定它为什么起作用或为什么我应该在我想工作的一段代码。理想情况下,我希望ON UPDATE CURRENT_TIMESTAMP
部分能够以某种方式工作,而不是在另一个 *** 问题上添加该用户提供的代码。
所以我真的有两个问题:
-
为什么我收到关于 ON UPDATE 部分的错误,尽管它是从源复制/粘贴的?
如何正确获取行以在更新行时自动更新其 LastUpdated 列?
【问题讨论】:
【参考方案1】:不幸的是,与 mysql 不同,SQLite 不支持 ON UPDATE CURRENT_TIMESTAMP
语法(我不确定 MySQL 是否真正提供该功能的任何其他数据库)。
解决此问题的一种方法是使用触发器。假设你的表的主键是id
,那就是:
CREATE TRIGGER Trg_LastUpdated
AFTER UPDATE ON Foo
FOR EACH ROW
BEGIN
UPDATE Foo SET LastUpdated = CURRENT_TIMESTAMP WHERE id = OLD.id;
END
Demo on DB Fiddle
【讨论】:
感谢您的快速响应,有什么方法可以检查我是否已经创建了这个触发器,所以我不会继续将它重新添加到我的数据库中?或者这是我不必担心的事情?我担心的是,如果多次执行此语句,它将创建重复的触发器,这些触发器都执行相同的操作,我假设这会产生性能问题。另一个问题是,您的 SQL 语句会更新所有行上的 LastUpdated 列还是只更新已更改的行? @DomStepek:(1) 您可以查询目录视图sqlite_master
以列出所有现有触发器,例如select * from sqlite_master where type = 'trigger';
。 (2) 这只会更新刚刚更新的行(前提是您有一个主键,如我的回答中所述)。以上是关于创建表列时如何正确使用 ON UPDATE CURRENT_TIMESTAMP?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle GoldenGate 生成表列时始终标识类型_IT 不允许在目标数据库表中插入
Derby Trigger on UPDATE:如何更新时间戳?
如何使用 sqlalchemy 在 mysql 中设置 DEFAULT ON UPDATE CURRENT_TIMESTAMP?
#1293 - 表定义不正确;在 DEFAULT 或 ON UPDATE 子句中只能有一个带有 CURRENT_TIMESTAMP 的 TIMESTAMP 列