2015-02-20 3 views
0

Я использую Mysql Workbench для моего класса базы данных в колледже, и даже довольно простой в использовании, есть некоторые вещи, которые я просто не могу работать вокруг.Добавление столбца со значением по умолчанию для даты послезавтра

Прямо сейчас, я застрял в попытке смоделировать магазин, похожий на блокбастер. на моей странице Аренда, я хочу добавить Exp_Ret_Date, Act_Ret_Date и Book_Date. Теперь Book_Date и Exp_Ret_Date имеют значения по умолчанию: Book_Date's имеет значение NOW(), а Exp_Ret_Date - через 2 дня после Book_Date.

Итак, я попытался написать DATE_ADD (NOW(), INTERVAL 2 DAY) в лагере по умолчанию, но он просто не работает. Я пытался использовать TIMESTAMP, CURDATE, ADDDATE и все, что мог придумать, но это не помогло. Итак, если кто-то может сориентировать меня на то, что я могу сделать, чтобы исправить это, меня и моих одноклассников было бы очень здорово.

Вот код, созданный MySQL Workbench. Он продолжал говорить о синтаксической ошибке в строке с частью DATE_ADD.

-- MySQL Workbench Forward Engineering 

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'; 

-- ----------------------------------------------------- 
-- Schema mydb 
-- ----------------------------------------------------- 

-- ----------------------------------------------------- 
-- Schema mydb 
-- ----------------------------------------------------- 
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ; 
USE `mydb` ; 

-- ----------------------------------------------------- 
-- Table `mydb`.`MEMBER` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`MEMBER` (
    `MEMBER_ID` INT(10) NOT NULL, 
    `LAST_NAME` VARCHAR(25) NOT NULL, 
    `FIRST_NAME` VARCHAR(25) NULL, 
    `ADDRESS` VARCHAR(100) NULL, 
    `CITY` VARCHAR(30) NULL, 
    `PHONE` VARCHAR(15) NULL, 
    `JOIN_DATE` DATETIME NOT NULL DEFAULT NOW(), 
    PRIMARY KEY (`MEMBER_ID`), 
    UNIQUE INDEX `MEMBER_ID_UNIQUE` (`MEMBER_ID` ASC)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`TITLE` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`TITLE` (
    `TITLE_ID` INT(10) NOT NULL, 
    `TITLE` VARCHAR(60) NOT NULL, 
    `DESCRIPTION` VARCHAR(400) NOT NULL, 
    `RATING` ENUM('G','PG','R','NC17','NR') NULL, 
    `CATEGORY` ENUM('DRAMA','COMEDY','ACTION','CHILD','SCIFI','DOCUMENTARY') NULL, 
    `RELEASE_DATE` DATETIME NULL, 
    PRIMARY KEY (`TITLE_ID`), 
    UNIQUE INDEX `TITLE_ID_UNIQUE` (`TITLE_ID` ASC)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`TITLE_COPY` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`TITLE_COPY` (
    `COPY_ID` INT(10) NOT NULL, 
    `STATUS` ENUM('AVAILIBLE','DESTROYED','RENTED','RESERVED') NOT NULL, 
    `TITLE_ID` INT(10) NOT NULL, 
    PRIMARY KEY (`COPY_ID`, `TITLE_ID`), 
    UNIQUE INDEX `COPY_ID_UNIQUE` (`COPY_ID` ASC), 
    INDEX `fk_TITLE_COPY_TITLE_idx` (`TITLE_ID` ASC), 
    CONSTRAINT `fk_TITLE_COPY_TITLE` 
    FOREIGN KEY (`TITLE_ID`) 
    REFERENCES `mydb`.`TITLE` (`TITLE_ID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`RENTAL` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`RENTAL` (
    `BOOK_DATE` DATETIME NOT NULL DEFAULT NOW(), 
    `ACT_RET_DATE` DATETIME NULL, 
    `EXP_RET_DATE` DATETIME NULL DEFAULT NOW() + INTERVAL 2 DAY, 
    `MEMBER_ID` INT(10) NOT NULL, 
    `COPY_ID` INT(10) NOT NULL, 
    `TITLE_ID` INT(10) NOT NULL, 
    PRIMARY KEY (`BOOK_DATE`, `COPY_ID`, `TITLE_ID`, `MEMBER_ID`), 
    UNIQUE INDEX `BOOK_DATE_UNIQUE` (`BOOK_DATE` ASC), 
    INDEX `fk_RENTAL_MEMBER1_idx` (`MEMBER_ID` ASC), 
    INDEX `fk_RENTAL_TITLE_COPY1_idx` (`COPY_ID` ASC, `TITLE_ID` ASC), 
    CONSTRAINT `fk_RENTAL_MEMBER1` 
    FOREIGN KEY (`MEMBER_ID`) 
    REFERENCES `mydb`.`MEMBER` (`MEMBER_ID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_RENTAL_TITLE_COPY1` 
    FOREIGN KEY (`COPY_ID` , `TITLE_ID`) 
    REFERENCES `mydb`.`TITLE_COPY` (`COPY_ID` , `TITLE_ID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`RESERVATION` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`RESERVATION` (
    `RES_DATE` DATETIME NOT NULL DEFAULT NOW(), 
    `MEMBER_ID` INT(10) NOT NULL, 
    `TITLE_ID` INT(10) NOT NULL, 
    PRIMARY KEY (`RES_DATE`, `MEMBER_ID`, `TITLE_ID`), 
    INDEX `fk_RESERVATION_MEMBER1_idx` (`MEMBER_ID` ASC), 
    INDEX `fk_RESERVATION_TITLE1_idx` (`TITLE_ID` ASC), 
    CONSTRAINT `fk_RESERVATION_MEMBER1` 
    FOREIGN KEY (`MEMBER_ID`) 
    REFERENCES `mydb`.`MEMBER` (`MEMBER_ID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_RESERVATION_TITLE1` 
    FOREIGN KEY (`TITLE_ID`) 
    REFERENCES `mydb`.`TITLE` (`TITLE_ID`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 


SET [email protected]_SQL_MODE; 
SET [email protected]_FOREIGN_KEY_CHECKS; 
SET [email protected]_UNIQUE_CHECKS; 

Заранее благодарим за любую помощь, которую вы можете предоставить. Ошибка в строке 72.

+2

'default' не может быть выражение, оно должно быть буквальным (или 'CURRENT_TIMESTAMP' как специальное исключение). Если вы хотите заполнить поля вычисленным значением автоматически, используйте триггер. – Barmar

ответ

0

Определения UNIQUE INDEX являются излишними, большинство из них не нужны.

Например, MEMBER_ID уже определен как PRIMARY KEY; второй уникальный индекс с этим столбцом в качестве ведущего столбца не нужен.

PRIMARY KEY (`MEMBER_ID`), 
UNIQUE INDEX `MEMBER_ID_UNIQUE` (`MEMBER_ID` ASC)) 

Я могу понять, что InnoDB не генерирует исключение; некоторые запросы могли бы использовать «узкий» индекс, но это был бы редкий случай использования, когда этот второй индекс фактически улучшает производительность. То же самое применимо и здесь:

PRIMARY KEY (`TITLE_ID`), 
UNIQUE INDEX `TITLE_ID_UNIQUE` (`TITLE_ID` ASC)) 

UNIQUE INDEX является излишним, так как TITLE_ID уже определен в качестве уникального ключа кластера для таблицы.

И это немного странно, COPY_ID уникален, но PRIMARY KEY определяется как комбинация этого уникального столбца, и второй столбец:

PRIMARY KEY (`COPY_ID`, `TITLE_ID`), 
UNIQUE INDEX `COPY_ID_UNIQUE` (`COPY_ID` ASC), 

Было бы достаточно просто сделать COPY_ID в PRIMARY KEY таблицы. То же самое относится и к этому ...

PRIMARY KEY (`BOOK_DATE`, `COPY_ID`, `TITLE_ID`, `MEMBER_ID`), 
UNIQUE INDEX `BOOK_DATE_UNIQUE` (`BOOK_DATE` ASC), 

Но в этом случае, я подозреваю, что BOOK_DATE не на самом деле уникален. Если это так, нет необходимости в составном первичном ключе.


Чтобы иметь базу данных автоматически присвоить значение столбца при вставке строки, вы можете определить BEFORE INSERT курок. (Как отметил Бармар в своем комментарии, MySQL ограничен в том, что он принимает как значение DEFAULT ... это должно быть значение буква, оно не может быть выражением. (С одним небольшим исключением для CURRENT_TIMESTAMP для TIMESTAMP столбцы, раньше вы могли делать это только в столбцах типа данных TIMESTAMP, но я думаю, что более новая версия MySQL поддерживает нечто подобное для столбцов DATETIME.)

В качестве простого примера триггера:

DELIMITER $$ 

CREATE TRIGGER mytable_bi 
BEFORE INSERT ON mytable 
FOR EACH ROW 
BEGIN 
    SET NEW.exp_ret_date = NOW() + INTERVAL 2 DAY; 
END$$ 

DELIMITER ; 

Триггер будет перекрывать любое значение, которое поставляется. Вы могли бы выполнить условный тест на спусковой крючок, чтобы проверить, является ли NULL значение столбца, перед присвоением ей значения:

IF NEW.exp_ret_date IS NULL THEN 
    SET NEW.exp_ret_date = NOW() + INTERVAL 2 DAY; 
    END IF; 
Смежные вопросы