#oracle
#Oracle
Вопрос:
вот мой оператор sql, все имена объектов разные, и я раньше не выполнял.
create table customer(
custno varchar(5) constraint custno not null,
custname varchar(20) constraint custname not null,
address varchar(25) constraint custadd not null,
internal char(1) constraint custinternal not null,
contact varchar(20) constraint custcontact not null,
phone integer constraint custph not null,
city varchar(10) constraint custcty not null,
state char(2) constraint state not null,
zip integer constraint custzip not null,
constraint pkcust primary key(custno)
);
create table facility(
facno varchar(5) constraint facno not null,
facname varchar(20) constraint facname not null,
constraint PKfac primary key(facno));
Ответ №1:
ORA-00955: имя уже используется существующим объектом
Это не обязательно должна быть сама таблица — это также может быть имя ограничения. Что это? Не могу сказать, но — если вы выполните эти команды в SQL * Plus, это укажет на виновника. Например:
SQL> create table customer (custno varchar2(5) constraint custno not null);
Table created.
SQL> create table facility (facno varchar2(5) constraint custno not null);
create table facility (facno varchar2(5) constraint custno not null)
*
ERROR at line 1:
ORA-02264: name already used by an existing constraint
SQL>
Видите звездочку? Указывает на точную точку ошибки (я назвал два ограничения с одинаковым именем).
Комментарии:
1. спасибо, я думаю, мне нужно провести надлежащее исследование протоколов!!
Ответ №2:
ORA-00955 четко указывает, что объект с тем же именем уже существует в вашей схеме.
Вы можете найти уже существующий объект с тем же именем, которое вы хотите присвоить своему объекту, используя представления метаданных следующим образом:
-- For tables:
SELECT *
FROM USER_OBJECTS
WHERE OBJECT_NAME IN (
'FACILITY',
'CUSTOMER'
);
-- for constarints
SELECT *
FROM USER_CONSTRAINTS
WHERE CONSTRAINT_NAME IN (
'PKFAC',
'FACNAME',
'FACNO',
'PKCUST',
'CUSTZIP',
'STATE',
'CUSTCTY',
'CUSTPH',
'CUSTCONTACT',
'CUSTINTERNAL',
'CUSTADD',
'CUSTNAME',
'CUSTNO'
);
Ответ №3:
ORA-00955: имя уже используется существующим объектом
Исключение не требует пояснений, вы используете идентификатор для объекта в базе данных, и этот идентификатор уже существует, чтобы однозначно идентифицировать другой объект (в той же схеме).
Например, у вас может быть таблица, идентифицируемая по имени state
, и вы пытаетесь создать ограничение с идентификатором state
.
В других ответах говорилось о том, где найти ошибку. Вместо этого я рассмотрю основную причину проблемы, и это отсутствие политики именования.
Когда вы называете таблицу, типичные соглашения об именовании должны давать ей описательное имя и либо всегда делать ее артиклем единственного числа (т. Е. customer
Или facility
), либо множественным числом (т. Е. customers
Или facilities
) и быть последовательными. Вы использовали единственное число, так что все в порядке.
Когда вы называете столбец, опять же, дайте ему описательное имя; не используйте сокращения, если вас не вынуждает ограничение на количество символов (и если вы это сделаете, вы можете добавить комментарий к столбцу с указанием полной информации); и вам не нужно включать имя таблицы в столбецимя, поскольку это избыточная информация (и дополнительные символы, которые разработчик должен вводить каждый раз, когда вы хотите использовать столбец).
Когда вы называете ограничение, снова дайте ему описательное имя, которое определяет, где и на что оно ссылается. Часто это включает в себя:
- тип ограничения (поскольку один столбец таблицы может иметь несколько ограничений);
- имя таблицы (поскольку может быть несколько таблиц, каждая из которых имеет одинаковое имя столбца); и
- имя столбца (поскольку в одной таблице в разных столбцах может быть несколько ограничений одного и того же типа).
Некоторые распространенные формулировки для имени ограничения будут tablename_columnname_(pk|fk|u|nn|chk)
или (pk|fk|u|nn|chk)_tablename_columnname
(в зависимости от того, хотите ли вы использовать имя таблицы или тип ограничения в качестве основных критериев для упорядочения ограничений при их поиске). Но какое бы соглашение об именовании вы ни использовали, вы должны убедиться, что вы последовательно применяете его во всей базе данных.
В зависимости от того, какое соглашение об именовании вы выбираете, ваш код может быть:
create table customer(
customer_no varchar2(5)
constraint customer_customer_no_nn not null
constraint customer_customer_no_pk primary key,
name varchar2(20)
constraint customer_name_nn not null,
address varchar2(25)
constraint customer_address_nn not null,
internal char(1)
constraint customer_internal_nn not null
constraint customer_internal_ck CHECK ( internal IN ( 'Y', 'N' ) ),
contact varchar2(20)
constraint customer_contact_nn not null,
phone integer
constraint customer_phone_nn not null,
city varchar2(10)
constraint customer_city_nn not null,
state char(2)
constraint customer_state_nn not null,
zip integer
constraint customer_zip_nn not null
);
create table facility(
facility_no varchar2(5)
constraint facility_facility_no_nn not null
constraint facility_facility_no_pk primary key,
name varchar2(20)
constraint facility_name_nn not null
);
(Кроме того, использование INTEGER
в качестве типа for phone
может показаться естественным, поскольку это числовые данные, но если номер телефона имеет начальные нули, то они будут удалены, и вы можете получить неверный номер телефона. Аналогично, zip
не всегда может быть числовым значением, когда вы имеете дело с международными клиентами, а их страна использует буквенно-цифровой почтовый индекс; но если вы будете иметь дело только с клиентами в одной стране, это может быть приемлемо.)
Комментарии:
1. Спасибо! это очень глубоко, будет использовать эти новые полученные знания.