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

时间:2017-01-06 22:42:05

标签: 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
)

错误是

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

3 个答案:

答案 0 :(得分:33)

两步流程

  1. 创建没有外键的表
  2. CREATE TABLE PLANETICKETS(
        DESTINATION VARCHAR(10) NOT NULL,
        TICKETPRICE NUMERIC(8,2) NOT NULL,
        TOURISTINFO_ID INT 
    )
    
    1. 添加外键约束
    2.  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)
      )
      

答案 1 :(得分:1)

我会在@ 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在数据库的每个副本中应分配相同的名称。但是,如果分配了直接名称(这是先前的迁移脚本中引用的名称),而不是通过检查单个数据库实例中分配的名称得出的直接名称,则不必担心。

答案 2 :(得分:-1)

我会改善@ david-brossard的答案:

action("Import Files")
            {
                ApplicationArea = All;
                Image = Import;

                trigger OnAction();
                var
                    FromFile: Text;
                    FileMgt: Codeunit "File Management";
                begin
                    Init();
                    Message(FileMgt.GetExtension('E:\Dynamically\' + 
                    Format(GetFileName)));
                    FromFile := 'E:\Dynamically\' + Format(GetFileName);
                    "Attached File".Import(FromFile);
                    "Attched File Name" := Format(GetFileName);
                    "Attached file Extension" := 
                     FileMgt.GetExtension(Format(GetFileName));
                    Insert(true);
                    MESSAGE('Successfully Import.');
                end;
            }

在这种情况下,您定义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列,因为H2知道哪一列是TOURISTINFO_ID中的主键。