Как получить первичный ключ с нулевыми значениями, используя пустую строку? - PullRequest
3 голосов
/ 11 марта 2010

У меня есть таблица, в которой мне нужно, чтобы оба значения были первичными, потому что я ссылаюсь на эту комбинацию как на внешний ключ в других таблицах. Определение таблицы и данные, которые мне нужно указать, следующие:

create table T1
(
  sno number(10),
  desc varchar2(10),
  constraint T1_PK primary key(sno,desc)
)
DATA to put
sno    | desc
---------------------------
100    | "hundred"
000    | null
120    | "one twenty"
123    | ""   <EMPTY STRING>
000    | ""   <EMPTY STRING>

Проблема здесь в том, что desc иногда может быть нулевым. Первичный ключ не может быть нулевым, поэтому, когда я сталкиваюсь с нулевым значением - я просто вставляю "" в таблицу. Проблема здесь в том, что иногда в desc может быть пустая строка. Если я вставлю данные «примерно 100», «Ноль» и «100», это две разные вещи, но я не смогу поместить их в таблицу. Я не хочу помещать какую-либо строку, например, «EMPTY», если она пуста, поскольку это может сбить с толку конечного пользователя, который смотрит на таблицу.

1) Как я могу обработать нулевой регистр для desc, имея его в качестве первичного ключа. Я не могу использовать автоматический порядковый номер. 2) Как я могу отличить введенную мною пустую строку от уже существующей?

Ответы [ 4 ]

8 голосов
/ 11 марта 2010

Почему бы вам не ввести настоящий атрибут первичного ключа (например, id), который автоматически увеличивается, и создать индекс по sno и desc?

6 голосов
/ 11 марта 2010

Oracle рассматривает пустые VARCHAR поля, как синоним NULL, который является несколько спорным, но это то, что вам придется жить с. Таким образом, вы не можете поместить пустую строку в первичный ключ, потому что вы не можете поместить NULL в первичный ключ.

Мой совет? Используйте технический первичный ключ, скажем, число (автоматически увеличивается в MySQL / SQL Server, с SEQUENCE в Oracle). Поместите уникальный индекс в пару других полей. Итак:

CREATE TABLE t1 (
  id NUMBER(10) PRIMARY KEY,
  sno NUMBER(10),
  desc VARCHAR2(10)
);
CREATE SEQUENCE t1_seq;
4 голосов
/ 11 марта 2010

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

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

Кто-то ДЕЙСТВИТЕЛЬНО сделал плохую работу над дизайном вашей базы данных. Увольнять плохо.

0 голосов
/ 12 марта 2010

Используйте CHAR вместо VARCHAR. Пусто будет пустым. Было бы необходимо установить пробел вместо пустой строки, чтобы Oracle не преобразовывал пустую строку в NULL. Обратите внимание, что в поле CHAR пробел такой же, как два пробела, три пробела ... (но он отличается от нуля пробелов для Oracle).

...