When creating a foreign key I am getting the error "Syntax error: missing 'closing parenthesis'

When creating a foreign key I am getting the error "Syntax error: missing 'closing parenthesis'

我正在使用 MySQL Workbench.
在行中:

REFERENCES section_t(section_id, semester, year)

我遇到错误

"Syntax error: missing 'closing parenthesis'". 

单词 'semester' 带有下划线,是错误的来源。

我不明白为什么 MySQL 要求右括号 here.I 构建了其他几个具有多个字段的外键并且工作正常,但在这个特定的地方我得到了一个错误。我以为我的保留字可能有问题,但事实并非如此。我也看不到我在错误的地方有任何括号,或者缺少一个。

如有帮助,将不胜感激。

这是SQL:

-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema cphillips03
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema cphillips03
-- -----------------------------------------------------
USE `cphillips03` ;
DROP TABLE IF EXISTS `cphillips03`.`advisor_t` ;
DROP TABLE IF EXISTS `cphillips03`.`classroom_t` ;
DROP TABLE IF EXISTS `cphillips03`.`course_t` ;
DROP TABLE IF EXISTS `cphillips03`.`department_t` ;
DROP TABLE IF EXISTS `cphillips03`.`instructor_t` ;
DROP TABLE IF EXISTS `cphillips03`.`instructor_t` ;
DROP TABLE IF EXISTS `cphillips03`.`prereq_t` ;
DROP TABLE IF EXISTS `cphillips03`.`section_t` ;
DROP TABLE IF EXISTS `cphillips03`.`student_t` ;
DROP TABLE IF EXISTS `cphillips03`.`takes_t` ;
DROP TABLE IF EXISTS `cphillips03`.`teaches_t` ;
DROP TABLE IF EXISTS `cphillips03`.`timeslot_t` ;

-- -----------------------------------------------------
-- Table `cphillips03`.`classroom_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`classroom_t` (
  `building` VARCHAR(15) NOT NULL DEFAULT '',
  `room_number` VARCHAR(7) NOT NULL DEFAULT '',
  `capacity` DECIMAL(4,0) NULL DEFAULT NULL,
  PRIMARY KEY (`building`, `room_number`))
;
-- -----------------------------------------------------
-- Insert commands for `cphillips03`.`classroom_t`
-- -----------------------------------------------------
insert into classroom_t values('Lamberton', 134, 10);

-- -----------------------------------------------------
-- Table `cphillips03`.`timeslot_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`timeslot_t` (
  `timeslot_id` VARCHAR(4) NOT NULL DEFAULT '',
  `day` VARCHAR(1) NOT NULL DEFAULT '',
  `start_hr` TIME NOT NULL DEFAULT '00:00:00',
  `start_min` TIME NOT NULL DEFAULT '00:00:00',
  `end_hour` TIME NULL DEFAULT NULL,
  `end_min` TIME NULL DEFAULT NULL,
  PRIMARY KEY (`timeslot_id`, `day`, `start_hr`, `start_min`))
 ;

-- -----------------------------------------------------
-- Table `cphillips03`.`department_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`department_t` (
  `dept_name` VARCHAR(20) NOT NULL DEFAULT '',
  `building` VARCHAR(15) NULL DEFAULT NULL,
  `budget` DECIMAL(12,2) NULL DEFAULT NULL,
  PRIMARY KEY (`dept_name`),
  FOREIGN KEY (building)
    REFERENCES classroom_t(building)
    ON UPDATE CASCADE
    )
 ;


-- -----------------------------------------------------
-- Table `cphillips03`.`course_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`course_t` (
  `course_id` VARCHAR(8) NOT NULL DEFAULT '',
  `title` VARCHAR(50) NULL DEFAULT NULL,
  `dept_name` VARCHAR(20) NULL DEFAULT NULL,
  `credits` DECIMAL(2,0) NULL DEFAULT NULL,
  PRIMARY KEY (`course_id`),
  FOREIGN KEY (dept_name)
    REFERENCES department_t(dept_name)
    ON UPDATE CASCADE
    )
;




-- -----------------------------------------------------
-- Table `cphillips03`.`instructor_t`
-- -----------------------------------------------------

CREATE TABLE IF NOT EXISTS `cphillips03`.`instructor_t` (
  `instructor_id` VARCHAR(5) NOT NULL DEFAULT '',
  `name` VARCHAR(20) NOT NULL,
  `dept_name` VARCHAR(20) NULL DEFAULT NULL,
  `salary` DECIMAL(8,2) NULL DEFAULT NULL,
  PRIMARY KEY (`instructor_id`),
  FOREIGN KEY (dept_name)
    REFERENCES department_t(dept_name)
    ON UPDATE CASCADE
    )
 ;


-- -----------------------------------------------------
-- Table `cphillips03`.`prereq_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`prereq_t` (
  `course_id` VARCHAR(8) NOT NULL DEFAULT '',
  `prereq_id` VARCHAR(8) NOT NULL DEFAULT '',
  PRIMARY KEY (`course_id`, `prereq_id`),
  FOREIGN KEY (course_id)
    REFERENCES course_t(course_id)
    ON UPDATE CASCADE
    )
 ;


-- -----------------------------------------------------
-- Table `cphillips03`.`section_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`section_t` (
  `course_id` VARCHAR(8) NOT NULL DEFAULT '',
  `section_id` VARCHAR(8) NOT NULL DEFAULT '',
  `semester` VARCHAR(6) NOT NULL DEFAULT '',
  `year` DECIMAL(4,0) NOT NULL DEFAULT '0',
  `building` VARCHAR(15) NULL DEFAULT NULL,
  `room_number` VARCHAR(7) NULL DEFAULT NULL,
  `timeslot_id` VARCHAR(4) NULL DEFAULT NULL,
  PRIMARY KEY (`course_id`, `section_id`, `semester`, `year`),
  FOREIGN KEY (course_id)
    REFERENCES course_t(course_id)
    ON UPDATE CASCADE,
  FOREIGN KEY (building, room_number)
    REFERENCES classroom_t(building, room_number)
    ON UPDATE CASCADE,
  FOREIGN KEY (timeslot_id)
    REFERENCES timeslot_t(timeslot_id)
    ON UPDATE CASCADE
    )
 ;


-- -----------------------------------------------------
-- Table `cphillips03`.`student_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`student_t` (
  `student_id` VARCHAR(5) NOT NULL DEFAULT '',
  `name` VARCHAR(20) NOT NULL,
  `dept_name` VARCHAR(20) NULL DEFAULT NULL,
  `tot_cred` DECIMAL(3,0) NULL DEFAULT NULL,
  PRIMARY KEY (`student_id`),
  FOREIGN KEY (dept_name)
    REFERENCES department_t(dept_name)
    ON UPDATE CASCADE
    )
 ;


-- -----------------------------------------------------
-- Table `cphillips03`.`takes_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`takes_t` (
  `takes_id` VARCHAR(5) NOT NULL DEFAULT '',
  `course_id` VARCHAR(8) NOT NULL DEFAULT '',
  `sec_id` VARCHAR(8) NOT NULL DEFAULT '',
  `semester` VARCHAR(6) NOT NULL DEFAULT '',
  `year` DECIMAL(4,0) NOT NULL DEFAULT '0',
  `grade` VARCHAR(2) NULL DEFAULT NULL,
  PRIMARY KEY (`takes_id`, `course_id`, `sec_id`, `semester`, `year`),
  FOREIGN KEY (course_id)
    REFERENCES course_t(course_id)
    ON UPDATE CASCADE,
  FOREIGN KEY (sec_id, semester, year)
    REFERENCES section_t(section_id, semester, year)
    ON UPDATE CASCADE
    )
;


-- -----------------------------------------------------
-- Table `cphillips03`.`teaches_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`teaches_t` (
  `teaches_id` VARCHAR(5) NOT NULL DEFAULT '',
  `course_id` VARCHAR(8) NOT NULL DEFAULT '',
  `sec_id` VARCHAR(8) NOT NULL DEFAULT '',
  `semester` VARCHAR(6) NOT NULL DEFAULT '',
  `year` DECIMAL(4,0) NOT NULL DEFAULT '0',
  PRIMARY KEY (`teaches_id`, `course_id`, `sec_id`, `semester`, `year`),
  FOREIGN KEY (course_id)
    REFERENCES course_t(course_id)
    ON UPDATE CASCADE
    )
 ;



-- -----------------------------------------------------
-- Table `cphillips03`.`advisor_t`
-- -----------------------------------------------------


CREATE TABLE IF NOT EXISTS `cphillips03`.`advisor_t` (
  `student_id` VARCHAR(5) NOT NULL DEFAULT '',
  `instructor_id` VARCHAR(5) NOT NULL DEFAULT '',
  PRIMARY KEY (`student_id`, `instructor_id`),
  FOREIGN KEY (student_id)
    REFERENCES student_t(student_id)
    ON UPDATE CASCADE,
  FOREIGN KEY (instructor_id)
    REFERENCES instructor_t(instructor_id)
    ON UPDATE CASCADE
    )
 ;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

主要解决方案

编辑:经过大量讨论,我们确定添加索引是解决此问题的最佳方案:

ALTER TABLE section_t
ADD INDEX( section_id, semester, year )

CREATE TABLE section_t (
...
INDEX( section_id, semester, year )

过去的历史讨论

好吧,我没有收到任何错误;您确定您使用的是最新版本的 mysql 吗?

代码运行:

CREATE TABLE IF NOT EXISTS takes_t (
takes_id VARCHAR(5) NOT NULL DEFAULT '',
course_id VARCHAR(8) NOT NULL DEFAULT '',
sec_id VARCHAR(8) NOT NULL DEFAULT '',
semester VARCHAR(6) NOT NULL DEFAULT '',
year DECIMAL(4, 0) NOT NULL DEFAULT '0',
grade VARCHAR(2) NULL DEFAULT NULL,
PRIMARY KEY( takes_id, course_id, sec_id, semester, year ),
FOREIGN KEY(course_id)
REFERENCES course_t(course_id)
ON UPDATE CASCADE,
FOREIGN KEY( sec_id, semester, year )
REFERENCES section_t( section_id, semester, year )
ON UPDATE CASCADE
)
ENGINE = INNODB
DEFAULT CHARACTER SET=utf8;

我收到以下回复:

Query OK, 0 rows affected

如果你发现什么请告诉我。

编辑:使用您的完整脚本,我在执行 takes_t 时遇到以下错误。我已单独输入所有查询:

ERROR 1215 (HY000): Cannot add foreign key constraint

当我在以下行时得到它:

FOREIGN KEY(sec_id, semester, year)
REFERENCES section_t( section_id, semester, year )

可能(尽管不太可能)的解决方案:将 sec_id 的所有实例替换为 section_id

更可能的解决方案:从 section_t 的主键中删除 course_id

原因:外键需要索引;主键的索引可能仅在使用完整主键时适用。