【问题标题】:Defining a Foreign key constraint in H2 Databases在 H2 数据库中定义外键约束
【发布时间】:2017-05-21 19:09:39
【问题描述】:

我是编码新手,所以我在 SQL Server 中创建了一个表,它可以工作,所以我在 H2 中使用了相同的命令,它说我的第二个表有语法问题,有人可以帮忙吗?

CREATE TABLE TOURISTINFO(
TOURISTINFO_ID INT PRIMARY KEY,
NAME VARCHAR(25) NOT NULL,
NATIONALITY VARCHAR(15) NOT NULL
)

CREATE TABLE PLANETICKETS(
DESTINATION VARCHAR(10) NOT NULL,
TICKETPRICE NUMERIC(8,2) NOT NULL,
TOURISTINFO_ID INT FOREIGN KEY REFERENCES TOURISTINFO
)

错误是

Syntax error in SQL statement "CREATE TABLE PLANETICKETS( 
DESTINATION VARCHAR(10) NOT NULL, 
TICKETPRICE NUMERIC(8,2) NOT NULL, 
TOURISTINFO_ID INT FOREIGN[*] KEY REFERENCES TOURISTINFO 
)"; expected "(, FOR, UNSIGNED, NOT, NULL, AS, DEFAULT, GENERATED, NOT, NULL, AUTO_INCREMENT, BIGSERIAL, SERIAL, IDENTITY, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, ,, )"; SQL statement:
CREATE TABLE PLANETICKETS( 
DESTINATION VARCHAR(10) NOT NULL, 
TICKETPRICE NUMERIC(8,2) NOT NULL, 
TOURISTINFO_ID INT FOREIGN KEY REFERENCES TOURISTINFO 
) [42001-173] 42001/42001

【问题讨论】:

  • 错误的确切措辞是什么?
  • SQL 语句中的语法错误“CREATE TABLE PLANETICKETS(DESTINATION VARCHAR(10) NOT NULL, TICKETPRICE NUMERIC(8,2) NOT NULL, TOURISTINFO_ID INT FOREIGN[*] KEY REFERENCES TOURISTINFO)”;预期“(,FOR,UNSIGNED,NOT,NULL,AS,DEFAULT,GENERATED,NOT,NULL,AUTO_INCREMENT,BIGSERIAL,SERIAL,IDENTITY,NULL_TO_DEFAULT,SEQUENCE,SELECTIVITY,COMMENT,CONSTRAINT,PRIMARY,UNIQUE,NOT,NULL,CHECK,参考文献, ,, )";

标签: sql database foreign-keys h2


【解决方案1】:

两步过程

  1. 创建没有外键的表
CREATE TABLE PLANETICKETS(
    DESTINATION VARCHAR(10) NOT NULL,
    TICKETPRICE NUMERIC(8,2) NOT NULL,
    TOURISTINFO_ID INT 
)
  1. 添加外键约束
 ALTER TABLE PLANETICKETS
    ADD FOREIGN KEY (TOURISTINFO_ID) 
    REFERENCES TOURISTINFO(TOURISTINFO_ID)

一步法

CREATE TABLE PLANETICKETS(
  DESTINATION VARCHAR(10) NOT NULL,
  TICKETPRICE NUMERIC(8,2) NOT NULL,
  TOURISTINFO_ID INT,
  foreign key (TOURISTINFO_ID) references touristinfo(TOURISTINFO_ID)
)

【讨论】:

【解决方案2】:

我会在@david-brossard 的回答中添加一个选项:

CREATE TABLE PLANETICKETS(
  DESTINATION VARCHAR(10) NOT NULL,
  TICKETPRICE NUMERIC(8,2) NOT NULL,
  TOURISTINFO_ID INT,

  CONSTRAINT FK_PLANETICKET_TOURIST FOREIGN KEY (TOURISTINFO_ID) REFERENCES TOURISTINFO(TOURISTINFO_ID)
)

通过使用Constaint Name Definition,外键被显式命名,否则 H2 会根据它自己的命名方案为其分配一个名称,例如CONSTRAINT_74。

我觉得通过避免名称使用的歧义和引用之前直接定义的名称,例如

ALTER TABLE PLANETICKETS DROP CONSTRAINT FK_PLANETICKET_TOURIST;
ALTER TABLE PLANETICKETS ADD CONSTRAINT FK_PLANETICKET_TOURIST FOREIGN KEY (TOURISTINFO_ID) REFERENCES TOURISTINFO(TOURISTINFO_ID)  ON DELETE CASCADE;

根据我对可安装软件产品的 Flyway 使用情况,我已开始将此作为标准操作。

理论上,Flyway 迁移的顺序应该导致约束(包括外键)以相同的顺序应用,因此 H2 应该在每个数据库副本中分配相同的名称。但是,如果分配了直接名称(在以前的迁移脚本中引用的名称)而不是通过检查单个数据库实例中分配的名称推断出的名称,则担心点会被消除。

【讨论】:

  • 不知道为什么你被否决为 0。这正是我想要的。这样我就可以用 mysql、mariadb 和 h2 中有效的语法创建一个命名外键
【解决方案3】:

我会改进 @david-brossard 的回答:

CREATE TABLE PLANETICKETS(
    DESTINATION VARCHAR(10) NOT NULL,
    TICKETPRICE NUMERIC(8,2) NOT NULL,
    TOURISTINFO_ID INT,
    FOREIGN KEY(TOURISTINFO_ID) REFERENCES TOURISTINFO -- no need for touristinfo(TOURISTINFO_ID)
)

当您在这种情况下定义 FOREIGN KEY 时,您可以省略显式引用 TOURISTINFO_ID 列,因为 H2 知道 PLANETICKETS 中的主键是哪一列。

【讨论】:

  • 我不知道你为什么被否决。实际上,我从我的经验中看到同样的问题有不同的解决方案,并且对不同的人有不同的工作方式。对我来说,其他解决方案不起作用,但您的解决方案正在起作用。我不知道,因为我记得我之前在H2数据库中创建了一个外键,就像上面的解决方案一样。但这一次它对我不起作用。我刚走到最后,看到了你的解决方案。它只需遵循“--不需要旅游信息(TOURISTINFO_ID)”即可。谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 2012-04-08
  • 2013-12-17
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2016-07-08
相关资源
最近更新 更多