在H2数据库中定义外键约束

l3k*_*kov 23 sql database foreign-keys h2

我是编码的新手,所以我在SQL服务器上创建了一个表并且它工作了,所以我在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
)
Run Code Online (Sandbox Code Playgroud)

错误是

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
Run Code Online (Sandbox Code Playgroud)

Dav*_*ard 39

两步过程

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

单向过程

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)
)
Run Code Online (Sandbox Code Playgroud)


Daz*_*zed 13

I would add one option to @david-brossard's answer:

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)
)
Run Code Online (Sandbox Code Playgroud)

By using a Constaint Name Definition the foreign key is named explicitly, otherwise H2 assigns it a name based on it's own naming scheme e.g. CONSTRAINT_74.

I feel this makes it safer to manage the constraint later by avoiding ambiguity on use of the name and referencing the name directly defined previously e.g.

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;
Run Code Online (Sandbox Code Playgroud)

I have started doing this as standard, based on my use of Flyway for an installable software product.

In theory the sequence of Flyway migrations should result in constraints (including Foreign Keys) being applied in the same order and therefore H2 should assign the same name in each copy of database. However, the worry point is removed if a direct name is assigned - one which is referenced in previous migration scripts - rather than one deduced from checking the assigned name in a single database instance.


dan*_*emi 5

我会改进@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)
)
Run Code Online (Sandbox Code Playgroud)

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