I am trying to create a table with an index but it's causing an ORA-00907 error which says I am missing a right parentheses. Here is my example sql that causes the error.
create table example
(
id number(12, 0) not null using index (create index example_idx on example(id))
);
Perhaps it is because of the not null keywords but I don't understand why it asks a right parenthesis.
create table and create index are separate statements, you can't mix them like that (although you can have an index implicitly or explicitly created to back up a unique or primary key constraint you define in-line).
You need to do this in two steps, as two separate statements:
create table example (id number(12, 0) not null);
create index example_idx on example(id);
The example you show from here:
CREATE TABLE a (
a1 INT PRIMARY KEY USING INDEX (create index ai on a (a1)));
is in a section titled 'Specifying the Index Associated with a Constraint', and
is creating the index as part of a primary key constraint. The using index clause is described here.
In your code you are created a not-null constraint, which is not backed by an index, so that clause is not valid here. You can only use this method of creating an index if it is to back a unique or primary key, as the link you provided says.
Related
I have a table in Oracle 11g such as with below columns.
COL1_STATUS
COL2_ID
COL3_TYPE
COL4_DATE
I want to create a UNIQUE constraint combining all 4 columns but only when COL1_STATUS = 10
How can I do that? Table is already created so I am looking for only ALTER command.
Also, I have searched and found similar question where it is suggested to use unique index but I want to achieve this by constraint.
Conditional unique constraint with multiple fields in oracle db
Thanks in advance.
A unique index and a constraint are essentially the same thing. A unique constraint is implement using a unique index. So this really should do what you want:
create unique index idx_table_4 on
table(case when status = 10 then id end,
case when status = 10 then type end,
case when status = 10 then date end);
In fact, this is how the documentation recommends implementing a unique constraint:
When you specify a unique constraint on one or more columns, Oracle
implicitly creates an index on the unique key. If you are defining
uniqueness for purposes of query performance, then Oracle recommends
that you instead create the unique index explicitly using a CREATE
UNIQUE INDEX statement. You can also use the CREATE UNIQUE INDEX
statement to create a unique function-based index that defines a
conditional unique constraint. See "Using a Function-based Index to
Define Conditional Uniqueness: Example" for more information.
I'm trying to setup an indexed view on a table that doesn't have a unique id. It has two unique identifiers that if combined would be unique for it's row. I'm having trouble actually creating the unique clustered index that the indexed view requires when I found an thread on MSDN that folks all agree it is possible to create a unique clustered index out of 2 columns for a indexed view # http://social.msdn.microsoft.com/Forums/en/transactsql/thread/f2c99845-3af1-46e8-9b52-363c24988744
But for the life of me, can't figure out how to create it. I'm rolling with this query, but it doesn't seem to cut it.
CREATE UNIQUE CLUSTERED INDEX [PK] ON MyView
(
MyId1, MyId2
)
Error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key
was found for the object name 'dbo.MyView' and the index name 'PK'.
The duplicate key value is (71cd9b68-1a9e-47bc-bc6b-0008b230a6d8,
0e64aa3a-0631-4caf-82d9-73609ee79b19).
The two IDs listed as duplicates are IDs from MyId2.
So, how could I create a unique clustered index here?
Well the error message seems to suggest that there is more than one record where MyId1 = 71cd9b68-1a9e-47bc-bc6b-0008b230a6d8 and MyId2 = 0e64aa3a-0631-4caf-82d9-73609ee79b19.
I would recommend running a query that selects based only on that criteria and confirming that this only returns one record. If it returns more, then you cannot recreate a UNIQUE constraint on these two columns unless you eliminate the duplicates.
I was creating a new table today in 10g when I noticed an interesting behavior. Here is an example of what I did:
CREATE TABLE test_table ( field_1 INTEGER PRIMARY KEY );
Oracle will by default, create a non-null unique index for the primary key. I double checked this. After a quick check, I find a unique index name SYS_C0065645. Everything is working as expected so far. Now I did this:
CREATE TABLE test_table ( field_1 INTEGER,
CONSTRAINT pk_test_table PRIMARY KEY (field_1) USING INDEX (CREATE INDEX idx_test_table_00 ON test_table (field_1)));
After describing my newly created index idx_test_table_00, I see that it is non-unique. I tried to insert duplicate data into the table and was stopped by the primary key constraint, proving that the functionality has not been affected. It seems strange to me that Oracle would allow a non-unique index to be used for a primary key constraint. Why is this allowed?
There is actually no structural difference between a unique index and a non-unique index, Oracle can use either for the PK constraint. One advantage of allowing a PK definition like this is that you can disable or defer the constraint for data loading - this isn't possible with a unique index, so one could argue that this implementation is more flexible.
Why not allow it? I love that Oracle gives you lots of options and flexibility.
Maybe you can create one index and use it for two purposes:
validate the PK
help a query perform better
Oracle will by default create a non-null unique index
Oh, and the index has nothing to do with the not null aspect.
see this excellent article about non-unique indexes policing primary keys by Richard Foote. Richard shows that you will take a performance hit when using a non-unique index.
In other words: don't use non-unique indexes to police a primary key constraint unless you really need the constraint to be deferrable.
I'd like to create a table:
CREATE TABLE sfc.OpenId (
Url VARCHAR(255) PRIMARY KEY,
UserGuid uniqueidentifier NOT NULL references dbo.aspnet_users(userId),
)
...with an index on UserGuid.
Is it possible to create that index in the create table statement?
You can do that if the index on UserGuid is a unique index, via UNIQUE constraint. Otherwise, no.
Is it possible to create that index in the create table statement?
No, only constraints can be created within the CREATE TABLE syntax.
f not defined otherwise, the primary key will automatically be a CLUSTERED index - but that doesn't cover the userguid column. The CREATE INDEX syntax needs to be a separate statement otherwise.
Can you clarify why?
You can use transactions with DDL in SQL server and for most purposes this is equivalent to doing it at the same time.
In SQL Server 2005+ (I use both), does adding the UNIQUE constraint to a column automatically create an index, or should I still CREATE INDEX?
See this MSDN article:
The Database Engine automatically
creates a UNIQUE index to enforce the
uniqueness requirement of the UNIQUE
constraint.
If you do create an index, you'll end up with two indexes, as this example demonstrates:
create table TestTable (id int)
alter table TestTable add constraint unique_id unique (id)
create unique index ix_TestTable_id on TestTable (id)
select * from sys.indexes where [object_id] = object_id('TestTable')
This will display two unique indexes on TestTable; and the HEAP that represents the table itself.
Yes, it does.
In fact, you can even create a CLUSTERED UNIQUE CONSTRAINT:
ALTER TABLE mytable ADD CONSTRAINT UX_mytable_col1 UNIQUE CLUSTERED (col1)
, which will make the table to be clustered on col1.
Almost all databases create an index for UNIQUE CONSTRAINT, otherwise it would be very hard to maintain it.
Oracle doesn't even distinguish between UNIQUE CONSTRAINT and UNIQUE INDEX: one command is just a synonym for another.
The only difference in Oracle is that a UNIQUE INDEX should have a user-supplied name, while a UNIQUE CONSTRAINT may be created with a system-generated name:
ALTER TABLE mytable MODIFY col1 UNIQUE
This will create an index called SYS_CXXXXXX.
An index is created when you add a unique constraint:
Reference -- see the second paragraph.
When a UNIQUE constraint is added to
an existing column or columns in the
table, by default, the Database Engine
examines the existing data in the
columns to make sure all values are
unique. If a UNIQUE constraint is
added to a column that has duplicated
values, the Database Engine returns an
error and does not add the constraint.
The Database Engine automatically
creates a UNIQUE index to enforce the
uniqueness requirement of the UNIQUE
constraint. Therefore, if an attempt
to insert a duplicate row is made, the
Database Engine returns an error
message that states the UNIQUE
constraint has been violated and does
not add the row to the table. Unless a
clustered index is explicitly
specified, a unique, nonclustered
index is created by default to enforce
the UNIQUE constraint.