ORA-02264: name already used by an existing constraint [duplicate] - sql

This question already has an answer here:
SQL error: "name already used by an existing constraint"
(1 answer)
Closed 7 years ago.
I Am Working On SQL And I Am Facing A Problem In Creating The Table!
Here Is My Code:
CREATE TABLE Voucher_Types
(
ID Number(3, 0),
Abbreviation VarChar(2),
Voucher_Type VarChar(100),
EntryBy VarChar(25),
EntryDate Date,
CONSTRAINT ID_PK Primary Key(ID)
);
And I Get The Following Error,
ORA-02264: name already used by an existing constraint
I Am Using Oracle10g
I Goggled It And Found Some Topics But They Didn't Help Me, Can Somebody Help Me In This Problem! Thanks In Advance..!

You have another table that has already a constrained with the name ID_PK.
If you want to find out which table it is, you might try
select owner, table_name from dba_constraints where constraint_name = 'ID_PK';
Most probably, you copied your create table statement but did not change the primary key's constraint name.
It is generally felt to be good practice to include the table name in a constraint's name. One reason is exactly to prevent such "errors".
So, in your case, you might use
CREATE TABLE Voucher_Types
(
...
CONSTRAINT Voucher_Types_PK Primary Key(ID)
);
Update Why can't the same constraint name be used twice? (As per your question in the comment): This is exactly because it is a name that identifies the constraint. If you have a violation of a constraint in a running system, you want to know which constraint it was, so you need a name. But if this name can refer multiple constraints, the name is of no particular use.

The error message tells you that there's already another constraint named ID_PK in your schema - just use another name, and you should be fine:
CREATE TABLE Voucher_Types
(
ID Number(3, 0),
Abbreviation VarChar(2),
Voucher_Type VarChar(100),
EntryBy VarChar(25),
EntryDate Date,
CONSTRAINT VOUCHER_TYPES_ID_PK Primary Key(ID)
);
To find the offending constraint:
SELECT * FROM user_constraints WHERE CONSTRAINT_NAME = 'ID_PK'

this means that there is a constraint named ID_PK try with
CONSTRAINT Voucher_Types_ID_PK Primary Key(ID) for instance
you can check whether exists with
select * from user_constraints where upper(constraint_name) = 'ID_PK';
or
select * from all_constraints where upper(constraint_name) = 'ID_PK';

you have same constraint name in other table
you need to change the constraint name
if you want to see table name which you used this constraint
you can see following query:
select table_name,constraint_name from user_constraints where lower(constraint_name)='id_pk';

The anwser of Frank Schmitt is good.
However for the name of your constraint you can also use the table alias as part of your constraint name.
The name of your constraint would be something like: vte_pk. And there is no necessary to invoke the name of the concerning column in the constraint name.
What if the primary key is over 2 (or more) columns?
Thus ... CONSTRAINT VTE_PK Primary Key(ID) ....

Related

Relation "table" already exists

I'm building a SQL database and running into the error "relation 'sexes' already exists".
Per SO users that posted about a similar problem, I've attempted: commenting out constraints to see if those were interfering, changing all references to serial/ all primary keys to integers to match up types, dropping all tables if they exist. The error remains the same no matter what I do so I've posted my original code. I could really use some guidance as to what the issue in this case is. Thanks!
CREATE TABLE sexes (
id serial PRIMARY KEY,
string text NOT NULL
);
CREATE TABLE humans (
id serial PRIMARY KEY UNIQUE NOT NULL,
forename text NOT NULL,
surname text NOT NULL,
birthdate date,
sex_id integer REFERENCES sexes(id)
);
CREATE TABLE marriages (
id serial PRIMARY KEY UNIQUE NOT NULL,
partner_1_id integer REFERENCES humans(id),
partner_2_id integer REFERENCES humans(id),
marriage_date date NOT NULL,
divorce_date date NOT NULL,
CONSTRAINT divorced CHECK (marriage_date <= divorce_date),
CONSTRAINT marry_self CHECK (partner_1_id <> partner_2_id)
);
You could use IF NOT EXISTS clause:
Do not throw an error if a relation with the same name already exists. A notice is issued in this case. Note that there is no guarantee that the existing relation is anything like the one that would have been created.
CREATE TABLE IF NOT EXISTS sexes (
id serial PRIMARY KEY,
string text NOT NULL
);
Which is really strange because dropping the tables if they existed before creating new ones threw back a whole new error.
If you want to drop tables you have to do it in right order:
DROP TABLE IF EXISTS marriages;
DROP TABLE IF EXISTS humans;
DROP TABLE IF EXISTS sexes;

Does oracle provide a built-in currency table for me to use as constraints?

I'm creating a table in Oracle 11g like this:
CREATE TABLE EXAMPLE (
ID VARCHAR2(10) PRIMARY KEY,
NAME VARCHAR2(100),
SHORT VARCHAR2(50),
CURRENCY CHAR(3)
);
Is it possible to create a foreign key constraint or even a check constraint on CURRENCY to a built-in Oracle table that contains the ISO currencies?
Not having a great understanding of databases I also take as input other solutions that might be out there, however I do not want to maintain my own table for this, if it's too much work, I'll live with user errors.
Thanks.
You can get a list of ISO currencies from a built in view in oracle:
select utl_i18n.GET_DEFAULT_ISO_CURRENCY(value) iso_cur
from v$nls_valid_values
where parameter = 'TERRITORY'
But as Nuno Guerreiro said, you'll need to create a table from these results and add a foreign key to the new table.
Note: Edited to include #A.B.Cade's suggestion.
Unfortunately you can't directly add a constraint, as the currencies data is available through a system a view. You can, however, create your own table with that information and then create the foreign key. Here's an example of how you can do it.
CREATE TABLE currencies (
country VARCHAR2(30) PRIMARY KEY,
currency VARCHAR2(3) NOT NULL
);
INSERT INTO currencies
SELECT value country, utl_i18n.get_default_iso_currency(value) currency
FROM v$nls_valid_values
WHERE parameter = 'TERRITORY';
CREATE INDEX currencies_iso_idx ON currencies(currency) COMPUTE STATISTICS;
ALTER TABLE example ADD CONSTRAINT example_currency_fk FOREIGN KEY (currency)
REFERENCES currencies(currency);
The example above includes an index on the currency value, as I suspect that will what you'll be querying on.
Actually I don't understand what do you mean by "default Oracle table that contains ISO currencies" (do you mean Oracle PeopleSoft CURRENCY_CD_TBL table?), but in general you can alter your table after creation to add foreign key constraint.
Here is an example:
ALTER TABLE EXAMPLE
ADD CONSTRAINT fk_currency
FOREIGN KEY (CURRENCY)
REFERENCES put_parent_table_name_here(_corresponding_field_name_in_perent_table);
You also can add constraint definition into CREATE TABLE statement.
Here is an example:
CREATE TABLE EXAMPLE (
ID VARCHAR2(10) PRIMARY KEY,
NAME VARCHAR2(100),
SHORT VARCHAR2(50),
CURRENCY CHAR(3),
CONSTRAINT fk_currency
FOREIGN KEY (CURRENCY)
REFERENCES put_parent_table_name_here(_corresponding_field_name_in_perent_table)
);

Integrity Constraint Invalid Identifier SQL

I am new to SQL and I am currently have an issue with a constraint I am trying to put on one of my columns.
My database models an art gallery and paintings can either be in the gallery or on loan to another gallery. Obviously it can't be both so I was trying to put a constraint on my on_loan table when creating it to stop the painting ID (P_id) of my on_loan table being the same as the P_id in my in_gallery table. This is what I have done so far:
create table in_gallery (
P_id NUMBER (10) CONSTRAINT PK_IN_GALLERY PRIMARY KEY,
CONSTRAINT IN_GALLERY_FK FOREIGN KEY(P_id) REFERENCES painting(P_id) ON DELETE CASCADE);
create table on_loan (
P_id NUMBER (10),
CONSTRAINT BOOK_IS_IN_GALLERY CHECK(P_id != in_gallery(P_id)));
This comes up with the error:
ERROR at line 3:
ORA-00904: "IN_GALLERY": invalid identifier
How would i fix this error?
Thanks.
You can't reference another table like that in a check constraint.
Check the answers to the question here for some solutions. You could achieve this with a user defined function.
EDIT: Also based on the little bit of information from your post I don't think you have a correct normalized database model. You could have a Gallery table and a Painting table with a relation between the two.

Adding column with primary key in existing table

I am trying to add primary key to newly added column in existing table name Product_Details.
New Column added: Product_Detail_ID (int and not null)
I am trying add primary key to Product_Detail_ID (please note: there are no other primary or foreign key assigned to this table)
I am trying with this query but getting error.
ALTER TABLE Product_Details
ADD CONSTRAINT pk_Product_Detils_Product_Detail_ID PRIMARY KEY(Product_Detail_ID)
GO
Error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Product\_Details' and the index name 'pk\_Product\_Detils'. The duplicate key value is (0).
Am I missing something here? I am using SQL Server 2008 R2. I would appreciate any help.
If you want SQL Server to automatically provide values for the new column, make it an identity.
ALTER TABLE Product_Details DROP COLUMN Product_Detail_ID
GO
ALTER TABLE Product_Details ADD Product_Detail_ID int identity(1,1) not null
GO
ALTER TABLE Product_Details
add CONSTRAINT pk_Product_Detils_Product_Detail_ID primary key(Product_Detail_ID)
GO
In mysql, I was able to achieve with following query
ALTER TABLE table_name ADD new_column int NOT NULL AUTO_INCREMENT primary key
Add Primary Key to First Position
ALTER TABLE table_name
ADD column_name INT PRIMARY KEY AUTO_INCREMENT FIRST;
Reference: Stack Overflow | Tech On The Net
You are getting the error because you have existing data that does not fullfill the constraint.
There are 2 ways to fix it:
clean up the existing data before adding the constraint
add the constraint with the "WITH NOCHECK" option, this will stop sql server checking existing data, only new data will be checked
ALTER TABLE Jaya
ADD CONSTRAINT no primary key(No);
here Jaya is table name,
no is column name,
ADD CONSTRAINT is we giving the primary key keyword
If you want to add a new column say deptId to the existing table say department then you can do it using the below code.
ALTER TABLE department ADD COLUMN deptID INT;
it will create your new column named deptID.
now if you want to add constraint also along with new column while creating it then you can do it using the below code. In the below code I am adding primary key as a constraint. you can add another constraint also instead of primary key like foreign key, default etc.
ALTER TABLE department ADD COLUMN deptID INT NOT NULL ADD CONSTRAINT PRIMARY KEY(deptID);
k. friend
command:
sql> alter table tablename add primary key(col_name);
ex: alter table pk_Product_Detils add primary key(Product_Detail_ID);

Correct way to create a table that references variables from another table

I have these relationships:
User(uid:integer,uname:varchar), key is uid
Recipe(rid:integer,content:text), key is rid
Rating(rid:integer, uid:integer, rating:integer) , key is (uid,rid).
I built the table in the following way:
CREATE TABLE User(
uid INTEGER PRIMARY KEY ,
uname VARCHAR NOT NULL
);
CREATE TABLE Recipes(
rid INTEGER PRIMARY KEY,
content VARCHAR NOT NULL
);
Now for the Rating table: I want it to be impossible to insert a uid\rid that does not exist in User\Recipe.
My question is: which of the following is the correct way to do it? Or please suggest the correct way if none of them are correct. Moreover, I would really appreciate if someone could explain to me what is the difference between the two.
First:
CREATE TABLE Rating(
rid INTEGER,
uid INTEGER,
rating INTEGER CHECK (0<=rating and rating<=5) NOT NULL,
PRIMARY KEY(rid,uid),
FOREIGN KEY (rid) REFERENCES Recipes,
FOREIGN KEY (uid) REFERENCES User
);
Second:
CREATE TABLE Rating(
rid INTEGER REFERENCES Recipes,
uid INTEGER REFERENCES User,
rating INTEGER CHECK (0<=rating and rating<=5) NOT NULL,
PRIMARY KEY(rid,uid)
);
EDIT:
I think User is problematic as a name for a table so ignore the name.
Technically both versions are the same in Postgres. The docs for CREATE TABLE say so quite clearly:
There are two ways to define constraints: table constraints and column constraints. A column constraint is defined as part of a column definition. A table constraint definition is not tied to a particular column, and it can encompass more than one column. Every column constraint can also be written as a table constraint; a column constraint is only a notational convenience for use when the constraint only affects one column.
So when you have to reference a compound key a table constraint is the only way to go.
But for every other case I prefer the shortest and most concise form where I don't need to give names to stuff I'm not really interested in. So my version would be like this:
CREATE TABLE usr(
uid SERIAL PRIMARY KEY ,
uname TEXT NOT NULL
);
CREATE TABLE recipes(
rid SERIAL PRIMARY KEY,
content TEXT NOT NULL
);
CREATE TABLE rating(
rid INTEGER REFERENCES recipes,
uid INTEGER REFERENCES usr,
rating INTEGER NOT NULL CHECK (rating between 0 and 5),
PRIMARY KEY(rid,uid)
);
This is a SQL Server based solution, but the concept applies to most any RDBMS.
Like so:
CREATE TABLE Rating (
rid int NOT NULL,
uid int NOT NULL,
CONSTRAINT PK_Rating PRIMARY KEY (rid, uid)
);
ALTER TABLE Rating ADD CONSTRAINT FK_Rating_Recipies FOREIGN KEY(rid)
REFERENCES Recipies (rid);
ALTER TABLE Rating ADD CONSTRAINT FK_Rating_User FOREIGN KEY(uid)
REFERENCES User (uid);
This ensures that the values inside of Rating are only valid values inside of both the Users table and the Recipes table. Please note, in the Rating table I didn't include the other fields you had, just add those.
Assume in the users table you have 3 users: Joe, Bob and Bill respective ID's 1,2,3. And in the recipes table you had cookies, chicken pot pie, and pumpkin pie respective ID's are 1,2,3. Then inserting into Rating table will only allow for these values, the minute you enter 4 for a RID or a UID SQL throws an error and does not commit the transaction.
Try it yourself, its a good learning experience.
In Postgresql a correct way to implement these tables are:
CREATE SEQUENCE uid_seq;
CREATE SEQUENCE rid_seq;
CREATE TABLE User(
uid INTEGER PRIMARY KEY DEFAULT nextval('uid_seq'),
uname VARCHAR NOT NULL
);
CREATE TABLE Recipes(
rid INTEGER PRIMARY KEY DEFAULT nextval('rid_seq'),
content VARCHAR NOT NULL
);
CREATE TABLE Rating(
rid INTEGER NOT NULL REFERENCES Recipes(rid),
uid INTEGER NOT NULL REFERENCES User(uid),
rating INTEGER CHECK (0<=rating and rating<=5) NOT NULL,
PRIMARY KEY(rid,uid)
);
There is no real difference between the two options that you have written.
A simple (i.e. single-column) foreign key may be declared in-line with the column declaration or not. It's merely a question of style. A third way should be to omit foreign key declarations from the CREATE TABLE entirely and later add them using ALTER TABLE statements; done in a transaction (presumable along with all the other tables, constraints, etc) the table would never exist without its required constraints. Choose whichever you think is easiest fora human coder to read and understand i.e. is easiest to maintain.
EDIT: I overlooked the REFERENCES clause in the second version when I wrote my original answer. The two versions are identical in terms of referential integrity, there are just two ways of syntax to do this.