#java #sql #database #jdbc #primary-key
#java #sql #База данных #jdbc #первичный ключ
Вопрос:
У меня есть первичный ключ, определенный как строковое значение. Итак, два кортежа с первичными ключами как «Hello» и «hello» не могут существовать, потому что первичный ключ не чувствителен к регистру.
Каким будет оператор sql для создания таблицы, первичный ключ которой не чувствителен к регистру?
Комментарии:
1. Прочитайте о противопоказаниях проверки: w3schools.com/sql/sql_check.asp
2. Какое контрольное ограничение я должен использовать?
Ответ №1:
Вам в основном нужно ограничение проверки, которое использует вспомогательный запрос. Но поскольку подзапросы не разрешены в контрольных ограничениях, вы можете написать функцию, которая выполняет запрос и возвращает результат: (Предполагая, что ваш PK называется ID)
create or replace
FUNCTION check_id(ID_INPUT IN VARCHAR2)
RETURN NUMBER
IS count_id NUMBER;
Begin
SELECT count(*) INTO count_id FROM table WHERE UPPER(ID_INPUT) = UPPER(ID);
Return(Count_Id);
END;
Затем используйте эту функцию в вашем контрольном ограничении для вашего первичного ключа
CHECK check_id(ID) = 0
Попробуйте это и дайте мне знать. Не проверял его на синтаксис.
Ответ №2:
Наличие определяемой пользователем функции, вызываемой ограничением, является одним из способов. Недостатки заключаются в том, что полное сканирование таблицы должно выполняться каждый раз, когда вставляется строка — или, я полагаю, всякий раз, когда обновляется ключевое поле, но это не должно происходить слишком часто. Кроме того, разработка udf, на который может ссылаться ограничение, не всегда проста. Даже если это разрешено, функция должна соответствовать строгим требованиям о детерминированности и не изменять состояние данных. Некоторые СУБД делают это относительно простым, others…do нет.
Другим вариантом было бы определить «теневое» поле. Это поле, заполненное триггерами вставки и обновления, будет содержимым поля ID, преобразованного во все регистры, верхние или нижние. Тогда уникальное ограничение на теневое поле будет служить нужной вам цели. Это также может быть реализовано как вычисляемый столбец, где они существуют, но триггеры были бы лучше. В случае дубликатов триггеры могут перехватывать исключение и создавать свои собственные, с полем ID вместо тени, названным виновником.
Недостатком этого метода является то, что вы удвоили пространство, необходимое для хранения ваших ключевых данных. Это может быть или не быть значительным.
Интересно, что Oracle 12c ввел столбец «невидимый». Он действует так же, как и любой другой столбец, за исключением того, что на него нужно явно ссылаться, например, он не отображается select *
. Это было бы идеальным использованием для такого невидимого столбца.