Реляционные базы данных проверяют ограничение ORACLE - PullRequest
0 голосов
/ 27 февраля 2019

Я работаю над проектом для Uni, и у меня мало знаний или опыта работы с базами данных.Я пытаюсь создать базу данных в Oracle с таблицей, которая содержит изготовленные детали, которые могут быть двух типов, скажем, 1 и 2. Когда деталь имеет тип 1, я буду хранить в таблице ее местоположение, когда она будет иметь тип 2 Iбудет хранить в той же таблице время выполнения.Таким образом, у меня будут нулевые значения для другого столбца в обоих случаях (я знаю о проблемах с нулевыми значениями, но подумав об этом и выяснив, как лучше всего с этим справиться, я решил сделать это так,так как у меня только небольшое количество атрибутов).Моя проблема в ПРОВЕРКЕ ПРОВЕРКИ.Я попытался сделать это следующим образом:

CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));

Это не работает.

Я попытался вставить запись следующим образом:

insert into manufactured(PID, PARTTYPE, LOCATION) values(101,1,'Warehouse1'); 

И я получаюошибка: ORA-02290: проверка ограничения (*****. LEADTIME) нарушена

Я также попытался:

insert into manufactured values (101,1,'Warehouse1');

И я получаю ошибку:

ORA-00947: недостаточно значений

И, наконец, с этим:

insert into manufactured(PID, PARTTYPE, LEAD_TIME) VALUES (102, 2, '2 WEEKS');

Я получаю следующую ошибку: ORA-02290: проверка ограничения (****. LEADTIME2) нарушена

Заранее благодарю за помощь.

Ответы [ 3 ]

0 голосов
/ 28 февраля 2019

Этот оператор вставки:

вставка в производственные (PID, PARTTYPE, LOCATION) значения (101,1, 'Warehouse1');

... не выполняетсяпотому что ваше ограничение LEADTIME требует, чтобы PARTTYPE=2.(Это условие AND, поэтому, если PARTTYPE=1 ограничение не будет выполнено независимо от значения LEAD_TIME.)

Это то, что, я думаю, вы ищете:

CREATE TABLE manufactured (
PID INT NOT NULL,
PARTTYPE NUMBER (1) NOT NULL,
CHECK (PARTTYPE IN (1,2)),
CONSTRAINT REFMAN FOREIGN KEY (PID, PARTTYPE) REFERENCES PART (PID, PARTTYPE),
LOCATION VARCHAR (50),
--CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL),
--CONSTRAINT LOC2 CHECK(PARTTYPE=2 AND LOCATION IS NULL),
CONSTRAINT LOC CHECK (PARTTYPE=1 AND LOCATION IS NOT NULL OR PARTTYPE=2 AND LOCATION IS NULL),
LEAD_TIME VARCHAR (50),
--CONSTRAINT LEADTIME CHECK (PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
--CONSTRAINT LEADTIME2 CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL),
CONSTRAINT LEADTIME CHECK (PARTTYPE=1 AND LEAD_TIME IS NULL OR PARTTYPE=2 AND LEAD_TIME IS NOT NULL),
CONSTRAINT PK_MAN PRIMARY KEY (PID));

По сути, создайте одно ограничение для каждого столбца, которое обеспечивает полный набор логики для этого столбца.

Если вы действительно хотите два ограничения для каждого столбца, вы можете сделать это тоже.Если так, оставьте комментарий, и я обновлю этот ответ.В противном случае я не хочу загромождать / путать проблему.

0 голосов
/ 28 февраля 2019
  • Ошибка ORA-00947: not enough values для

    insert into manufactured values (101,1,'Warehouse1'); очевидна,

    с момента последнего столбца (lead_time) таблицы (manufactured)отсутствует в списке values.

  • Ошибки ORA-02290: check constraint проистекают из зависимых условий среди проверочных ограничений LEADTIME и LEADTIME2, их следует объединить как
    CONSTRAINT LEADTIME CHECK ((PARTTYPE=2 AND LEAD_TIME IS NOT NULL) OR (PARTTYPE=1 AND LEAD_TIME IS NULL)).

  • Та же логика работает и для ограничений LOC и LOC2, которые должны давать

    CONSTRAINT LOC CHECK ((PARTTYPE=1 AND LOCATION IS NOT NULL) OR (PARTTYPE=2 AND LOCATION IS NULL))

0 голосов
/ 28 февраля 2019

Я не знаю, какую СУБД вы используете.Например, в Oracle CHECK ограничение принимает пустые значения.

Как я вижу, существуют разные атрибуты / типы данных для каждого типа партии.Существует два подхода:

  1. разделить данные на две отдельные таблицы.В этом решении могут быть необходимы некоторые триггеры.
    • tab1: изготовлено_1 (атрибуты + ограничения для PID 1)
    • tab2: изготовлено_2 (атрибуты + ограничения для PID 2)
  2. use "после вставки/ update "триггер - он установит ненужные данные в ноль.Например, если в таблице будет время для PID = 1, триггер установит значение времени на ноль.
...