SQLite: убедитесь, что одна запись меньше другой в качестве ограничения - PullRequest
1 голос
/ 23 октября 2011

Интересно, как решить эту проблему.

Я получил две таблицы

Table1 ( t1_prim , t1_int) с t1_prim в качестве первичного ключа и t1_int не нулевым.

Table2 ( t2_prim1 , t2prim2 , t2_int) с t2_prim1 и t2_prim2 в качестве ограничения первичного ключа и внешнего ключа t2_prim1 ссылается на t1_prim.

как я могу определить ограничение, которое гарантирует, что никто не вводит целое число в t2_int, которое больше, чем соответствующая запись в t1_int?

Я попробовал это так (не работает, потому что вы не можете вводить подзапросы в проверочном ограничении):

CREATE TABLE table2 
  (t2_prim1 TEXT,
  t2_prim2 INTEGER,
  t2_int INTEGER NOT NULL,
  PRIMARY KEY (t2_prim1, t2_prim2),
  FOREIGN KEY (t2_prim1) REFERENCES table1(t1_prim),
  CHECK (t2_int2 <= (SELECT t1_int2 FROM table1 WHERE t1_int1=t2_int1)));

И я думаю, что была бы другая проблема, если бы она работала так. Как мне проверить, что это ограничение все еще выполняется при изменении t1_int?

1 Ответ

2 голосов
/ 29 октября 2011

Наконец-то нашел ответ на мой вопрос.Вы можете решить проблему с помощью триггеров.Вот рабочий пример:

CREATE TABLE table1
  (t1_prim TEXT PRIMARY KEY,
   t1_int INTEGER NOT NULL);

CREATE TABLE table2
  (t2_prim1 TEXT,
  t2_prim2 INTEGER,
  t2_int INTEGER NOT NULL,
  PRIMARY KEY (t2_prim1, t2_prim2),
  FOREIGN KEY (t2_prim1) REFERENCES table1(t1_prim));

Создание триггеров для обновления и вставки:

CREATE TRIGGER t1_int_update_constraint
BEFORE UPDATE OF t1_int ON table1
  BEGIN
    SELECT CASE 
      WHEN new.t1_int < (SELECT max(t2_int) FROM table2 WHERE t2_prim1=old.t1_prim) 
        THEN (SELECT RAISE(ABORT, 
          'Input smaller than maximum of all values for t2_int in database!'))
      END;
  END;

CREATE TRIGGER t2_int_update_constraint
BEFORE UPDATE OF t2_int ON table2
  BEGIN
    SELECT CASE 
      WHEN new.t2_int > (SELECT t1_int FROM table1 WHERE t1_prim=old.t2_prim1) 
        THEN (SELECT RAISE(ABORT, 
         'Input bigger than value in t1_int!'))
      END;
    END;

CREATE TRIGGER t2_int_insert_constraint
BEFORE INSERT ON table2
  BEGIN
    SELECT CASE 
      WHEN new.t2_int > (SELECT t1_int FROM table1 WHERE t1_prim=new.t2_prim1) 
        THEN (SELECT RAISE(ABORT, 
         'Input bigger than value in t1_int!'))
      END;
  END;

Если у вас есть следующие таблицы:

table1

t1_prim     t1_int
----------  ----------
one         5         
two         10   

table2

t2_prim1    t2_prim2    t2_int    
----------  ----------  ----------
one         1           5         
one         2           4         
two         1           7         
two         2           5         
two         3           1         

Вы получите этот вывод:

UPDATE table1 SET t1_int=4 WHERE t1_prim='one';

Ошибка: вход меньше максимального значения всех значенийдля t2_int в базе данных!

UPDATE table1 SET t1_int=6 WHERE t1_prim='two';

Ошибка: ввод меньше максимального значения всех значений t2_int в базе данных!

UPDATE table2 SET t2_int=8 WHERE t2_prim1='one' AND t2_prim2=1;

Ошибка: ввод значения больше, чем значение в t1_int!

UPDATE table2 SET t2_int=11 WHERE t2_prim1='two' AND t2_prim2=2;

Ошибка: Ввод больше, чем значение в t1_int!

INSERT INTO table2 VALUES ('one', 3, 6);

Ошибка: Ввод больше, чем значение в t1_int!

В то время как те работают отлично:

INSERT INTO table2 VALUES ('one', 3, 6);
UPDATE table2 SET t2_int=1 WHERE t2_prim1='one' AND t2_prim2=1;
UPDATE table1 SET t1_int=8 WHERE t1_prim='two';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...