GENERATED ALWAYS AS IDENTITY 使用 UCanAccess 生成不正确的表模式

Posted

技术标签:

【中文标题】GENERATED ALWAYS AS IDENTITY 使用 UCanAccess 生成不正确的表模式【英文标题】:GENERATED ALWAYS AS IDENTITY produces incorrect table schema with UCanAccess 【发布时间】:2018-02-19 12:00:49 【问题描述】:

我正在使用 JDBC/UCanAccess 编写程序,我发现当我创建其中一个表时,它不是创建具有 DateTime 格式的四列,而是将相同的格式应用于下一列,取代另一列格式:

CREATE TABLE Person (
    Id INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
    Name VARCHAR(40), 
    Surname VARCHAR(40), 
    Card VARCHAR(9), 
    Email VARCHAR(30)
);

CREATE TABLE Place (
    Id INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
    Name VARCHAR(40)
);


CREATE TABLE Activity (
    Id INT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
    Name VARCHAR(40) NOT NULL, 
    Description1 VARCHAR(500), 
    Description2 VARCHAR(500), 
    Id_Person INT, 
    Hour_Start DATETIME, 
    Hour_End DATETIME, 
    Date_Plan_Start DATETIME, 
    Date_Plan_End DATETIME, 
    Cost CURRENCY, 
    Sale CURRENCY, 
    Id_Place INT, 
    CONSTRAINT fk_person_activity FOREIGN KEY (Id_Person) REFERENCES Person (Id), 
    CONSTRAINT fk_place_activity FOREIGN KEY (Id_Place) REFERENCES Place (Id)
);

它似乎在 Date_Plan_End 之前完成了所有操作,但创建的表将 Cost 作为 DateTime,将 Id_Place 作为 Currency。如果有人能告诉我为什么会发生这种情况,我将不胜感激。

编辑:错误仍然发生,仅插入以下内容:

CREATE TABLE Activity (
    Id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
    Name VARCHAR(40) NOT NULL, 
    Date_Plan_End DATETIME, 
    Cost CURRENCY, 
    Sale CURRENCY, 
    Id_Place INT, 
    PRIMARY KEY (Id)
);

SQL and outcome

这个问题似乎与生成的始终作为身份(START WITH 1, INCREMENT BY 1)有关。它的移除阻止了位移的发生,虽然我不知道为什么。

【问题讨论】:

所以,这就是生成的 SQL。请您显示编写的生成此代码的代码吗? 我不确定你的意思,如果你说的是,它不是由任何函数创建的代码。我几乎按原样写了它。它应该是代码的一部分,该代码将设置一个空白数据库,其中包含所需的表和一些用于测试的条目。唯一涉及的变量是两个来确定 varchar 长度,当我看到有错误时,这是​​我改变的第一件事。并且考虑到如果我直接通过 ucanaccess 控制台传递 SQL 也会发生错误,我认为传递 SQL 命令的程序中的函数不会出现问题。 那么,Activity.Cost 列上方的代码设置为DATETIME?你能展示一些证明这已经发生的事情吗?我以前从未在任何数据库上看到过这样的症状。同样,您是否可以尝试慢慢简化表的 DDL,直到症状消失? (如果您删除外键,它仍然会发生吗?如果您删除 VARCHAR(500) 列,它仍然会发生吗?您可以找到问题仍然存在的最小示例是什么?) 【参考方案1】:

这个问题似乎与生成的始终作为身份(START WITH 1, INCREMENT BY 1)有关。它的移除阻止了位移的发生

那是因为... GENERATED ALWAYS AS IDENTITY ... 是 HSQLDB DDL 语法,而 UCanAccess 使用 Access SQL DDL 语法。因此,而不是

CREATE TABLE Activity (
    Id INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), 
    Name VARCHAR(40) NOT NULL, 
    Date_Plan_End DATETIME, 
    Cost CURRENCY, 
    Sale CURRENCY, 
    Id_Place INT, 
    PRIMARY KEY (Id)
);

你应该使用

CREATE TABLE Activity (
    Id COUNTER PRIMARY KEY, 
    Name VARCHAR(40) NOT NULL, 
    Date_Plan_End DATETIME, 
    Cost CURRENCY, 
    Sale CURRENCY, 
    Id_Place INT
);

【讨论】:

以上是关于GENERATED ALWAYS AS IDENTITY 使用 UCanAccess 生成不正确的表模式的主要内容,如果未能解决你的问题,请参考以下文章

GENERATED ALWAYS | 的限制是多少?默认情况下 作为 PostgreSQL 中的身份?

Datastage装载数据报错 -798 428C9 不能把一个值插入到用GENERATED ALWAYS定义的ROWID列

如何让 Slick 3 生成 BIGSERIAL 而不是 GENERATED BY DEFAULT AS IDENTITY?

IDENT_CURRENT 返回 NULL

怎样处理“error C2220: warning treated as error - no object file generated”错误

Cast from XCUIElement to unrelated type '[AnyObject]' always fails while fetching JSON