Primary Key supported by a non-unique index?

Encountered a weird situation today. A utility we setup which allows Analysts to restore data into their tables, started failing when it attempted to drop an index. The index was supporting a Primary Key. Makes sense. But our script was supposed to only be attempting to drop/recreate non-unique indexes. Turns out the supporting index on the Primary Key was non-unique, and to the best of my knowledge came about as follows:
SQL> create table junk (f number(1));
Table created.
SQL> create index junk_ix on junk(f);
Index created.
SQL> select UNIQUENESS from DBA_INDEXES where index_name = 'JUNK_IX';
UNIQUENES
NONUNIQUE
SQL> alter table forbesc.junk add constraint junk_pk primary key (f) using index junk_ix;
Table altered.
SQL> select UNIQUENESS from DBA_INDEXES where index_name = 'JUNK_IX';
UNIQUENES
NONUNIQUE
SQL> insert into junk values (1);
1 row created.
SQL> insert into junk values (1);
insert into junk values (1)
ERROR at line 1:
ORA-00001: unique constraint (FORBESC.JUNK_PK) violated
SQL> select index_name from dba_constraints where constraint_name = 'JUNK_PK';
INDEX_NAME
JUNK_IXWhat I can't figure out is how a non-unique index is enforcing uniqueness. I thought that it was the key in that very same process. I thought that perhaps an index with the 'SYS_123456' was getting created, perhaps, but I couldn't find one:
SQL> select object_name, object_type from dba_objects order by created desc;
OBJECT_NAME   OBJECT_TYPE
JUNK_IX     INDEX
JUNK     TABLE
...How is the uniqueness getting enforced in this case? This is in Oracle 11.1.0.7
Thanks,
--=Chuck

It has always been that way. Oracle can, and will, use a non-unique index to enforce a PK constraint, The existing index just needs to have the PK column(s) as the leading column(s) of the index:
SQL> create table t (id number, id1 number, descr varchar2(10));
Table created.
SQL> create index t_ids on t(id, id1);
Index created.
SQL> select index_name from user_indexes
  2  where table_name = 'T';
INDEX_NAME
T_IDS
SQL> alter table t add constraint t_pk
  2  primary key (id);
Table altered.
SQL> select index_name from user_indexes
  2  where table_name = 'T';
INDEX_NAME
T_IDS
SQL> insert into t values (1, 1, 'One');
1 row created.
SQL> insert into t values (1, 2, 'Two');
insert into t values (1, 2, 'Two')
ERROR at line 1:
ORA-00001: unique constraint (OPS$ORACLE.T_PK) violatedJohn

Similar Messages

  • Unique index vs non-unique index

    Hi Gurus,
    I'm getting lots of "TABLE ACCESS FULL" for lots of columns which have non-unique indexes is some queries. So my question is does optimizer does not pick up non-unique index but only pickes up unique indexes for those columns.
    Thanks
    Amitava.

    amitavachatterjee1975 wrote:
    Hi Gurus,
    I'm getting lots of "TABLE ACCESS FULL" for lots of columns which have non-unique indexes is some queries. So my question is does optimizer does not pick up non-unique index but only pickes up unique indexes for those columns.
    Thanks
    Amitava.WHY MY INDEX IS NOT BEING USED
    http://communities.bmc.com/communities/docs/DOC-10031
    http://searchoracle.techtarget.com/tip/Why-isn-t-my-index-getting-used
    http://www.orafaq.com/tuningguide/not%20using%20index.html

  • Non Unique Indexes on Dimension Table

    Hello ,
      I have Material Dimension that has Product MainGroup, Brand , SPC code broken from Product Hierarchy.
      As per Business Requirement , we don't want to use the Product Hierarchy , that should need to split into 3 pieces.
      Since The Cube Dimensions already reached the 13 , we can not increase the dimensions to keep these 3 fields into separate dimensions.
      I heard from Basis guy as <b>we can have index on three fields in same dimension table</b> & read some negative impact on aggregate definition.
      Is it true , which one is true , am not sure.
      Which one impact causes more worst & usefull..?
      Could please some experts throw some light on this.
    Cheers
    Martin

    Martin -
    Not sure what you mean by "read some negative impact on aggregate definition".
    But as far as adding additional indices on other columns of a dimension table, that certainly is doable. I have never done this as part of an actual intentiional design, but it seems like a valid apporach if you are limited by dimensions.  I'm assuming when you say you already have 13, that the 13 does not include the three standard dimensions for time, request, (drawing a blank, is it currency), so that you really have 16 dimensions, 13 of which are user defined. 
    We have added dimension tabl e indices in our shop when we have found large dimension tables that, either from poor initial design, or changes to the data and/or queries, have resulted in full tables scans against large dimension tables.  In some cases, the query costs of the full scan of the dimension table was more than the cost for the access of the fact table itself.
    These indices must be added by your DBA as they can not be added thru the Admin Wkbench.  You should also probably keep a record of any of these indices you create because if for some reason you delete the tables and reactivate the cube, you'll probably lose them.
    Pizzaman

  • Can we change the fields of database unique index in a customised table?

    Hi all..
    I want to know that can we create or change or delete the database unique index of a customized table?
    In my case, there is a customised table with 4 primary keys with all the records to be maintained thru transaction code SM30.
    There is database unique index maintained for this table which has 2 fields. These 2 fields are out of the 4 primary fields of the table.I hope I have made myself clear!
    Now when I am trying to insert a record in the table it give me a short dump.( It says duplication of records is not allowed)
    The reason being that the new record that I am trying to insert in the database table has those 2 fields for which the unique index is maintained is the same as an already existing record.And the other two fields are different from the already existing record.So overall the combination of the 4 primary fields is different.
    Please tell me how shall I proceed now?
    I also tried to change the Unique index but it is asking me some kind of authrization(You are not authorized to make changes (authorization object S_DEVELOP)).Also I am not sure whether changing the unique index is feasible or not.?
    Thanks.

    hi
    I think you will not be able to do unique indexing withou the help of primary keys,so use all the primary keys into the table field selections  and and then create indexing otherwise dupilication of keys can occur. if you are not able to keep the primary keys then go for non unique key indexing,where you have to add the client field and the any keys of your wish.

  • Can I have a primary key as a non-unique column

    Hi all,
    I have a table with 35 columns and only one column in a not null column. But this column data is not unique. I want to create a primary key with non-unique index, can I don it, if it is not possible is there any other way to it. Please help me with this.
    Thanks for your help.vinaykotha

    1) Do the 'Unique Column combination' check first, using this example. (Pl. Change the column name and number of columns you consider as candidate key.) The SQL as follows:-
    ;WITH CTE (ProductKey, CustomerKey, SalesTerritoryKey, DupRec)
     AS
      (SELECT ProductKey, CustomerKey, SalesTerritoryKey, ROW_NUMBER() OVER
         (PARTITION BY ProductKey, CustomerKey, SalesTerritoryKey
          ORDER BY ProductKey, CustomerKey, SalesTerritoryKey) AS DupRec
       FROM dbo.FactSales 
    SELECT *
    FROM CTE
    WHERE DupRec > 1
    2) if CTE Table returns no records, you are good to create a Composite CLUSTERED PRIMARY KEY, like:
    ALTER TABLE dbo.FactSales
    ADD CONSTRAINT PK_ProductKey_CustomerKey_SalesTerritoryKey 
    PRIMARY KEY CLUSTERED (ProductKey, CustomerKey, SalesTerritoryKey);
    If no error..bingo! if NOT, Don't worry, create a Composite Index like this:-
    3)
    CREATE NONCLUSTERED INDEX [IX_ProductKey_CustomerKey_SalesTerritoryKey] 
    ON dbo.FactSales(ProductKey, CustomerKey, SalesTerritoryKey);
    This will work still efficiently. Usually all transaction table are like that like Daily_Order table, Ship_Details table etc.
    -NC

  • UNIQUE INDEX and PRIMARY KEYS

    Hi Friends,
    I am confused about primary keys.
    What is the purpose of this key again? I know it is used for unique constraints.
    Supposing I have a table with two (2) columns which are each indexed as unique.
    Then they can me both candidate at primary key right?
    So why do I need a primary key again? when I have 2 columns which are uniquely index?
    Thanks a lot

    A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. This constraint does not apply to NULL values except for the BDB storage engine. For other engines, a UNIQUE index allows multiple NULL values for columns that can contain NULL
    The differences between the two are:
    1. Column(s) that make the Primary Key of a table cannot be NULL since by definition; the Primary Key cannot be NULL since it helps uniquely identify the record in the table. The column(s) that make up the unique index can be nullable. A note worth mentioning over here is that different RDBMS treat this differently –> while SQL Server and DB2 do not allow more than one NULL value in a unique index column, Oracle allows multiple NULL values. That is one of the things to look out for when designing/developing/porting applications across RDBMS.
    2. There can be only one Primary Key defined on the table where as you can have many unique indexes defined on the table (if needed).
    3. Also, in the case of SQL Server, if you go with the default options then a Primary Key is created as a clustered index while the unique index (constraint) is created as a non-clustered index. This is just the default behavior though and can be changed at creation time, if needed.
    So, if the unique index is defined on not null column(s), then it is essentially the same as the Primary Key and can be treated as an alternate key meaning it can also serve the purpose of identifying a record uniquely in the table.

  • PRIMARY KEY PARTITIONED INDEXES 생성방법 (ORA-2429, ORA-1408)

    제품 : ORACLE SERVER
    작성날짜 : 2004-08-13
    PRIMARY KEY PARTITIONED INDEXES 생성방법 (ORA-2429, ORA-1408)
    ============================================================
    PURPOSE
    primary key partitioned indexes 를 생성하는 방법을 알아 봅니다.
    SCOPE
    Oracle Partitioning Option은 8~10g Standard Edition에서는 지원하지
    않는다.
    Example:
    SQL> -- 먼저 partitioned table TEST_A 를 생성합니다.
    SQL>
    SQL> CREATE TABLE test_a (col1 number, col2 number, col3 varchar2(20))
    2 PARTITION BY RANGE (col1, col2)
    3 (partition part_test_a_1 values less than (10, 100),
    4 partition part_test_a_2 values less than (20, 200),
    5 partition part_test_a_3 values less than (30, 300),
    6 partition part_test_a_4 values less than (40, 400));
    Table created.
    SQL> -- partitioned table TEST_B 를 생성합니다.
    SQL>
    SQL> CREATE TABLE test_b (col1 number, col2 number, col3 varchar2(20))
    2 PARTITION BY RANGE (col1, col2)
    3 (partition part_test_b_1 values less than (10, 100),
    4 partition part_test_b_2 values less than (20, 200),
    5 partition part_test_b_3 values less than (30, 300),
    6 partition part_test_b_4 values less than (40, 400));
    Table created.
    SQL> -- TEST_A 테이블에
    SQL> -- non-unique local partitioned index, IX_TEST_A 를 생성합니다.
    SQL>
    SQL> CREATE INDEX ix_test_a ON test_a(col1, col2)
    2 LOCAL
    3 (partition ix_test_a_1,
    4 partition ix_test_a_2,
    5 partition ix_test_a_3,
    6 partition ix_test_a_4);
    Index created.
    SQL> -- TEST_B 테이블에
    SQL> -- unique global partitioned index, IX_TEST_B 를 생성합니다.
    SQL>
    SQL> CREATE UNIQUE INDEX ix_test_b1 ON test_b(col1, col2)
    2 GLOBAL PARTITION BY RANGE (col1, col2)
    3 (partition ix_test_b1_1 values less than (20, 200),
    4 partition ix_test_b1_2 values less than (maxvalue, maxvalue));
    Index created.
    SQL> -- TEST_A 테이블에 rimary key constraint (PK_TEST_A) 를 추가 합니다.
    SQL>
    SQL> ALTER TABLE test_a ADD CONSTRAINT pk_test_a
    2 PRIMARY KEY (col2, col1);
    Table altered.
    SQL> -- index IX_TEST_A 를 drop 하려고 하면 다음 에러가 발생합니다.
    SQL>
    SQL> DROP INDEX ix_test_a;
    drop index ix_test_a
    ERROR at line 1:
    ORA-02429: cannot drop index used for enforcement of unique/primary key
    SQL> -- TEST_B 테이블에 partition IX_TEST_B1 에서 사용된 같은 columns 들을 사용해서
    SQL> -- 새로운 두번째 index (IX_TEST_B2) 를 생성하려고 하면
    SQL> -- 다음 에러가 발생합니다.
    SQL>
    SQL> CREATE INDEX ix_test_b2 ON test_b(col1, col2)
    2 LOCAL;
    create index ix_test_b2 on test_b(col1, col2)
    ERROR at line 1:
    ORA-01408: such column list already indexed
    SQL> -- TEST_B 테이블에 primary key constraint (PK_TEST_B) 를 추가 합니다.
    SQL>
    SQL> ALTER TABLE test_b ADD CONSTRAINT pk_test_b
    2 PRIMARY KEY (col1, col2);
    Table altered.
    SQL> -- index IX_TEST_B1 를 drop 하려고 하면 다음 에러가 발생합니다.
    SQL>
    SQL> DROP INDEX ix_test_b1;
    drop index ix_test_b1
    ERROR at line 1:
    ORA-02429: cannot drop index used for enforcement of unique/primary key
    SQL> -- indexes 들과 각 indexes 이 걸려있는 tables 의 목록입니다.
    SQL>
    SQL> SELECT index_name, partition_name, status
    2 FROM user_ind_partitions
    3 ORDER BY index_name, partition_name;
    INDEX_NAME PARTITION_NAME STATUS
    IX_TEST_A IX_TEST_A_1 USABLE
    IX_TEST_A IX_TEST_A_2 USABLE
    IX_TEST_A IX_TEST_A_3 USABLE
    IX_TEST_A IX_TEST_A_4 USABLE
    IX_TEST_B1 IX_TEST_B1_1 USABLE
    IX_TEST_B1 IX_TEST_B1_2 USABLE
    6 rows selected.
    SQL> -- TEST_A 테이블에서 primary key constraint 를 drop 합니다.
    SQL>
    SQL> ALTER TABLE test_a DROP CONSTRAINT pk_test_a;
    Table altered.
    SQL> -- TEST_B 테이블에서 primary key constraint 를 drop 합니다.
    SQL>
    SQL> ALTER TABLE test_b DROP CONSTRAINT pk_test_b;
    Table altered.
    SQL> -- indexes 들과 각 indexes 이 걸려있는 tables 의 목록을 다시 봅니다.
    SQL> -- 여기서 주의해서 보아야 할 것은 non-unique local partitioned index (IX_TEST_A)
    SQL> -- 은 drop 되지 않고 USABLE 상태로 남아 있다는 것입니다.
    SQL> -- 이렇게 되는 이유는 index (IX_TEST_A) 가 non-unique 이기 때문입니다.
    SQL> -- 반면 unique global partitioned index (IX_TEST_B) 은 drop 되었습니다.
    SQL>
    SQL> SELECT index_name, partition_name, status
    2 FROM user_ind_partitions
    3 ORDER BY index_name, partition_name;
    INDEX_NAME PARTITION_NAME STATUS
    IX_TEST_A IX_TEST_A_1 USABLE
    IX_TEST_A IX_TEST_A_2 USABLE
    IX_TEST_A IX_TEST_A_3 USABLE
    IX_TEST_A IX_TEST_A_4 USABLE
    만일 index 가 primary key 에 정의되어 있는 columns 들과 같은 columns
    을 사용해서 만들어 졌다면 primary key 는 그 underlying index 를 사용합니다.
    이것은 index 가 unique 이건 non-unique 이건 또는 global 이건 local partioned index
    이건 관계없이 적용됩니다.
    위의 예제에서 primary key 가 non-unique index 위에 생성되었다는 것을
    주의해 보시기 바랍니다. 이렇게 되는 이유는 index 안의 값들이 사실
    모두 unique 하기 때문입니다. 그렇지 않을 경우 다음 에러가 발생하게 됩니다.
    "ORA-02437: cannot enable (STEELY.PK_TEST_B) - primary key violated."
    2개의 indexes 가 같은 순서의 같은 columns 을 사용해서 만들어 질 수는 없습니다.
    위의 예제에서 TEST_B 테이블에 두번째 index (IX_TEST_B2) 를 만들려고
    했을때 다음에러가 발생하는것을 확인할 수 있었습니다.
    "ORA-01408: such column list already indexed."
    하지만 columns 들의 순서를 바꾼다면 같은 columns 들을 사용하더라도
    추가적으로 indexes 를 생성할 수 있습니다.
    index (IX_TEST_A) 와 primary key (PK_TEST_A) 에 정의된 column 순서는
    반대로 되어 있습니다. 그러나 primary key 는 IX_TEST_A 를 underlying index
    로 사용하고 있습니다.
    테이블에서 primary key constraint 가 drop 되었을때
    만일 index 가 UNIQUE index 로 생성되었다면 대응하는 index 또한 drop 됩니다.
    이 현상은 LOCAL 또는 GLOBAL partitioned indexes 모두에 적용됩니다.
    partitioning 을 최대한 활용하기 위해서는 partitioned tables/indexes
    를 생성할 때에 STORAGE clause 를 반드시 사용해야 합니다.
    Reference Documents
    <Note:74224.1>

    First, thanks for posting the code that lets us reproduce your test. That is essential for issues like this.
    Because the primary key is global you will not be able to use
    INCLUDING INDEXES
    WITH VALIDATION;And you will need to add the primary key to the temp table
    ALTER TABLE DEMO_INTERVAL_DATA_LOAD_Y ADD CONSTRAINT IDX_DEMO_ROLL_Y PRIMARY KEY (ROLL_NUM);The the exchange will work. You will need to rebuild the primary key after the exchange.

  • Difference between Primary Key and Unique+Not NUll

    Hi Guys,
    Is there any difference the column being declared as primary key or unique+NOT NULL.
    Please let me know the internal and application point of view.
    Thanks in advance!
    Ranjan

    957590 wrote:
    Ok,Thanks however I donot think Primary key uses unique indexPK uses whatever index you specify - unique or not (as long as index is on proper column(s)). However, if you do not specify any index, PK creates unique index:
    SQL> create table tbl(
      2                   id number,
      3                   name varchar2(10)
      4                  )
      5  /
    Table created.
    SQL> alter table tbl
      2    add constraint tbl_pk
      3      primary key(
      4                  id
      5                 )
      6  /
    Table altered.
    SQL> select  index_name,
      2          uniqueness
      3    from  user_indexes
      4    where table_name = 'TBL'
      5  /
    INDEX_NAME                     UNIQUENES
    TBL_PK                         UNIQUE
    SQL> select  constraint_name,
      2          index_name
      3    from  user_constraints
      4    where table_name = 'TBL'
      5  /
    CONSTRAINT_NAME                INDEX_NAME
    TBL_PK                         TBL_PK
    SQL>  alter table tbl
      2    drop primary key
      3  /
    Table altered.
    SQL> create index tbl_non_unique_pk_index
      2    on tbl(
      3           id
      4          )
      5  /
    Index created.
    SQL> alter table tbl
      2    add constraint tbl_pk
      3      primary key(
      4                  id
      5                 )
      6        using index tbl_non_unique_pk_index
      7  /
    Table altered.
    SQL> select  index_name,
      2          uniqueness
      3    from  user_indexes
      4    where table_name = 'TBL'
      5  /
    INDEX_NAME                     UNIQUENES
    TBL_NON_UNIQUE_PK_INDEX        NONUNIQUE
    SQL> select  constraint_name,
      2          index_name
      3    from  user_constraints
      4    where table_name = 'TBL'
      5  /
    CONSTRAINT_NAME                INDEX_NAME
    TBL_PK                         TBL_NON_UNIQUE_PK_INDEX
    SQL> insert
      2    into tbl
      3    values(
      4           1,
      5           'A'
      6          )
      7  /
    1 row created.
    SQL> insert
      2    into tbl
      3    values(
      4           2,
      5           'B'
      6          )
      7  /
    1 row created.
    SQL> insert
      2    into tbl
      3    values(
      4           1,
      5           'C'
      6          )
      7  /
    insert
    ERROR at line 1:
    ORA-00001: unique constraint (SCOTT.TBL_PK) violated
    SQL> SY.

  • Unique or primary key on timestamp with timezone

    Hi,
    I have been experimenting with a date column in a primary key, or actually I tried using a timestamp with time zone in a primary key.
    While researching whether there was a way to avoid ORA-02329, I found the following:
    K15> create table dumdum
      2    (datum date not null
      3    ,naamp varchar2( 30 ) not null);
    Table created.
    K15>
    K15> alter table dumdum
      2    add constraint d_pk
      3        primary key
      4          (datum, naamp)
      5    using index;
    Table altered.
    K15>
    K15> select ind.index_type
      2  from   user_indexes ind
      3  where  ind.index_name = 'D_PK';
    INDEX_TYPE
    NORMAL
    1 row selected.
    K15>
    K15> insert into dumdum
      2    (datum
      3    ,naamp )
      4  select sysdate - (level/1440)
      5  ,      'nomen nescio'
      6  from   dual
      7  connect by level < 1000
      8  ;
    999 rows created.
    K15>
    K15> analyze index d_pk validate structure;
    Index analyzed.
    K15> analyze table dumdum compute statistics;
    Table analyzed.
    K15>
    K15> select naamp
      2  from   dumdum
      3  where  datum > to_date('16-06-2011 15.46.16', 'dd-mm-yyyy hh24.mi.ss' )
      4 
    K15> For the last select statement I get the following "explain plan":
    SELECT STATEMENT  CHOOSE
              Cost: 2  Bytes: 247  Cardinality: 13       
         1 INDEX RANGE SCAN UNIQUE D_PK
                    Cost: 3  Bytes: 247  Cardinality: 13  This behavior lived up to my expectations.
    Then, I tried this:
    K15> create table dumdum
      2    (datum date not null
      3    ,naamp varchar2( 30 ) not null);
    Table created.
    K15>
    K15> alter table dumdum
      2    add constraint d_pk
      3        primary key
      4          (datum, naamp)
      5    using index;
    Table altered.
    K15>
    K15> alter table dumdum
      2        modify datum timestamp(6) with time zone;
    Table altered.
    K15>
    K15> select ind.index_type
      2  from   user_indexes ind
      3  where  ind.index_name = 'D_PK';
    INDEX_TYPE
    NORMAL
    1 row selected.
    K15>
    K15> insert into dumdum
      2    (datum
      3    ,naamp )
      4  select sysdate - (level/1440)
      5  ,      'nomen nescio'
      6  from   dual
      7  connect by level < 1000
      8  ;
    999 rows created.
    K15>
    K15> analyze index d_pk validate structure;
    Index analyzed.
    K15> analyze table dumdum compute statistics;
    Table analyzed.
    K15>
    K15> select naamp
      2  from   dumdum
      3  where  datum > to_date('16-06-2011 15.46.16', 'dd-mm-yyyy hh24.mi.ss' )
      4
    K15> So, at first glance, the alter table statement to change the datatype from DATE to TIMESTAMP seems like a way of fooling Oracle. But the explain plan reveals a different story:
    SELECT STATEMENT  CHOOSE
              Cost: 4  Bytes: 1,25  Cardinality: 50       
         1 TABLE ACCESS FULL DUMDUM
                    Cost: 4  Bytes: 1,25  Cardinality: 50  I was only fooling myself. :-0
    But I wasn't done with my research:
    K15> create table dumdum
      2    (datum timestamp(6) with time zone not null
      3    ,naamp varchar2( 30 ) not null);
    Table created.
    K15>
    K15> create unique index d_ind
      2      on dumdum
      3           (datum, naamp);
    Index created.
    K15>
    K15>
    K15> select ind.index_type
      2  from   user_indexes ind
      3  where  ind.index_name = 'D_IND';
    INDEX_TYPE
    FUNCTION-BASED NORMAL
    1 row selected.
    K15>
    K15> insert into dumdum
      2    (datum
      3    ,naamp )
      4  select systimestamp - (level/1440)
      5  ,      'nomen nescio'
      6  from   dual
      7  connect by level < 1000
      8  ;
    999 rows created.
    K15>
    K15> analyze index d_ind validate structure;
    Index analyzed.
    K15> analyze table dumdum compute statistics;
    Table analyzed.
    K15>
    K15> select naamp
      2  from   dumdum
      3  where  datum > to_date('16-06-2011 15.56.16', 'dd-mm-yyyy hh24.mi.ss' )
      4
    K15>Now, my explain plan looks fine:
    SELECT STATEMENT  CHOOSE
              Cost: 2  Bytes: 1,25  Cardinality: 50       
         1 INDEX RANGE SCAN UNIQUE D_IND
              Cost: 3  Bytes: 1,25  Cardinality: 50  Why is Oracle so adamant about not allowing a timestamp with time zone in a unique key? And, given their position on the matter, where does their tolerance for a unique index come from?
    By the way, if I had a say in it, I would not allow anything that even remotely looks like a date to be part of a primary key, but that's another discussion.
    Thanks,
    Remco
    P.S. All this is on Oracle9i Enterprise Edition Release 9.2.0.8.0. Is it different on 10g or 11g?

    See if this helps. You can create primary key for TIMESTAMP WITH LOCAL TIME ZONE datatype.
    SQL>CREATE TABLE Mytimezone(Localtimezone TIMESTAMP WITH LOCAL TIME ZONE primary key, Location varchar2(20) );
    Table created.
    http://download.oracle.com/docs/cd/B19306_01/server.102/b14225/ch4datetime.htm#i1006169
    TIMESTAMP WITH LOCAL TIME ZONE Datatype
    TIMESTAMP WITH LOCAL TIME ZONE is another variant of TIMESTAMP. It differs from TIMESTAMP WITH TIME ZONE as follows: data stored in the database is normalized to the database time zone, and the time zone offset is not stored as part of the column data. When users retrieve the data, Oracle returns it in the users' local session time zone. The time zone offset is the difference (in hours and minutes) between local time and UTC (Coordinated Universal Time, formerly Greenwich Mean Time).
    Thanks
    http://swervedba.wordpress.com/

  • Composite Primary key & Primary key questions

    Background:
    1.5 TB data warehouse. All tables use at least a 3 column composite Primary key. Most use 3. col1||col2||col3 to achieve uniqueness.
    col1= very low cardinality. 99% of the values are '0'
    col2 = high cardinality. (SSN's, loaded monthly)
    col3 = low cardinality. (monthly sequence number used for partitioning)
    From what I've read, the first column used in a composite primary key also receives its own index. If that is correct, then the primary key being used is losing its effectiveness by putting a very low cardinality column as the first column of the Primary key. By moving col2 to the first position of the composite key, I would be obtaining an index on SSN which would be much more useful. (Please correct me if I'm wrong) Or since the index would be so large anyway, the CBO would just do full table scans which is what I'm trying to get away from.
    This Primary key is used to ensure uniqueness during loads. Other than that, it really has no purpose and is never queried by the user. (WHERE col1||col2||col3 = xxxxxxxxx)
    As a DBA, I see this massive tablespace for holding the primary keys now reaching in excess of 157 GB and it seems like such a waste of space. The problem I'm running across is how to ensure uniqueness during the loads w/o having to store the unique values. (the 157 GB) If I drop the PK's, then create unique indexes just for the loads, then the unique index would be generated against the entire table, which would take forever.
    If you create a local index (what I want in the end) it still has to create the index for all previous partitions (250+ partitions). You can't create a specific 'local' index on a partition. You create a local index on the table and when a new partition is added, the index is then added as well. That's what I want to do with some of my fields like SSN but for loading purposes, this isn't going to help me.
    I need a way to ensure uniqueness during a monthly load of a new partition (col1||col2||col3) but w/o having to store these values for eternity. Right now it's the primary key, so it has to be stored. I hope I'm making sense here. Any ideas?

    I think you need some clarification about the index supporting the primary key.
    The primary key is unique - the database will enforce this for you.
    All of the columns in the primary key are in the index that enforces the key (not just the first column).
    Usually this index is a unique index, but you can have a non-unique index supporting a primary key.
    I'm a little confused with some of your other statements
    how to ensure uniqueness during the loads w/o having to store the unique valuesIf you don't store the value how do you know it is unique?
    Did you mean that you don't want to store the key values in both the table and the index?
    You may want to consider making col3 (the partition key) the leading column of the index, so you can create a local (instead of global) PK index.
    I wouldn't worry too much about col1 (the column full of mostly zeros) - numbers are stored variable length. A NUMBER(38) that holds a zero takes no more space than a NUMBER(1) that holds a zero.

  • Primary Key modification

    Hello,
    I have a table with a primary key. There is an implicit index that is created with primary key - now I wish to alter this primary key so that I can use an another existing non-unique index (or by creating a new unique index). is there a way to achieve this? there are a lot of referentials associated with this primary key; hence I do not want to drop this primary key and re-create one.
    Thanks,
    Onkar

    Parent Table -
    +
    CREATE TABLE TEST_PARENT_1
    PARENT_ID VARCHAR2(2 BYTE),
    PARENT_NAME VARCHAR2(20 BYTE),
    PT_TIME TIMESTAMP(6)
    TABLESPACE T1
    LOGGING
    PARTITION BY RANGE (PT_TIME)
    PARTITION P1 VALUES LESS THAN (TIMESTAMP' 2012-04-01 00:00:00')
    LOGGING
    NOCOMPRESS
    TABLESPACE T1,
    PARTITION P2 VALUES LESS THAN (TIMESTAMP' 2012-05-01 00:00:00')
    LOGGING
    NOCOMPRESS
    TABLESPACE T1
    NOCOMPRESS
    NOCACHE
    NOPARALLEL
    MONITORING;
    CREATE UNIQUE INDEX PARENT_ID_1_PK ON TEST_PARENT_1
    (PARENT_ID)
    LOGGING
    TABLESPACE T1
    NOPARALLEL;
    CREATE UNIQUE INDEX TEST_PARENT_IDX_1 ON TEST_PARENT_1
    (PARENT_ID, PT_TIME)
    TABLESPACE T1
    LOGGING
    LOCAL (
    PARTITION P1
    LOGGING
    NOCOMPRESS
    TABLESPACE T1,
    PARTITION P2
    LOGGING
    NOCOMPRESS
    TABLESPACE T2
    NOPARALLEL;
    ALTER TABLE TEST_PARENT_1 ADD (
    CONSTRAINT PARENT_ID_1_PK
    PRIMARY KEY
    (PARENT_ID)
    USING INDEX PARENT_ID_1_PK);
    +
    Child Table -
    +
    CREATE TABLE TEST_CHILD_1
    PARENT_ID VARCHAR2(2 BYTE),
    CHILD_ID VARCHAR2(2 BYTE),
    CHILD_FIRST_NAME VARCHAR2(20 BYTE),
    CHILD_LAST_NAME VARCHAR2(20 BYTE),
    PT_TIME TIMESTAMP(6)
    TABLESPACE T1
    LOGGING
    PARTITION BY RANGE (PT_TIME)
    PARTITION P1 VALUES LESS THAN (TIMESTAMP' 2012-04-01 00:00:00')
    LOGGING
    NOCOMPRESS
    TABLESPACE T1,
    PARTITION P2 VALUES LESS THAN (TIMESTAMP' 2012-05-01 00:00:00')
    LOGGING
    NOCOMPRESS
    TABLESPACE T1
    NOCOMPRESS
    NOCACHE
    NOPARALLEL
    MONITORING;
    CREATE UNIQUE INDEX CHILD_ID_1_PK ON TEST_CHILD_1
    (CHILD_ID)
    LOGGING
    TABLESPACE T1
    NOPARALLEL;
    ALTER TABLE TEST_CHILD_1 ADD (
    CONSTRAINT CHILD_ID_1_PK
    PRIMARY KEY
    (CHILD_ID)
    USING INDEX CHILD_ID_1_PK);
    ALTER TABLE TEST_CHILD_1 ADD (
    CONSTRAINT FK_TEST_CHILD_1
    FOREIGN KEY (PARENT_ID)
    REFERENCES TEST_PARENT_1 (PARENT_ID)
    ON DELETE CASCADE);
    +
    I want to use TEST_PARENT_IDX_1 index for primary key in the TEST_PARENT_1 table. I hope this snippet helps.

  • Primary key  not getting altered

    Hi,
    I dropeed the Primary key and recreated it with an additional column, but I am getting "name already used by an existing object error". Please advise.
    ALTER TABLE acct DROP PRIMARY KEY CASCADE;
    ALTER TABLE acct ADD (
    CONSTRAINT acct_PK
    PRIMARY KEY
    (ACCT_ID,AS_OF_DT)
    USING INDEX);
    What changes do I need to do to this sql?
    Regards

    Check this out -- Dropping primary key, doesn't  drop associated index in 10G
    This resembles yours.
    From same post,
    1]
    Richard Foote (an Oracle ACE Employee & an 'Index' guru) says -
    >
    Remember, Oracle will only drop an index automatically if the Index is unique, the default behaviour is to keep a non-unique index that polices at PK constraint.
    >
    2]
    Dion Cho (Oracle ACE Member) also demonstrated -
    >
    Even with unique index, Oracle seems to deny to drop corresponding index when Index was explicitly created.
    >
    Please go through the post and workouts carefully.
    Edited by: ranit B on Dec 22, 2012 1:58 PM

  • Can EJB 3.0 beans be used with tables that do not have a primary key?

    Can a EJB 3.0 persistence bean be used with tables that do not have a primary key defined? I am building a test application based on the HowTo - Building EJB 3.0 Faces App paper posted after Openworld (schalk). The issue I am running into when trying to run the application is: Exception Description: Entity class [class com.persistence.Rpthead] has no primary key specified. Note: I get a simular error when using toplink directly.
    The tables I am binding to do not have primary keys defined. They use unique constraints to manage the table integrity.
    Is it possible to use EJB 3.0 on tables without a primary key? If not, are there plans to support this in the future?

    The spec requires a primary key Id annotation. I will take your suggestion to EJB 3.0 expert group.
    Can you also send an email to [email protected] with your requirement?
    -Debu

  • Unique Index Created Automatically on FK Columns

    Referencing the following document under Forward Engineering, http://www.oracle.com/technetwork/developer-tools/datamodeler/newfeatures30-224506.html
    Unique index is created for One-to-one relationships defined in the Logical model if there is no PK/UK constraint or unique index defined over foreign key columns.
    Why are unique indexes created automatically for foreign key columns? Should "lookups" not be defined in the logical model? I don't understand why it's designed to behave that way.

    Why are unique indexes created automatically for foreign key columns? They are created automatically only for 1:1 relationships in order to support that business rule.
    Should "lookups" not be defined in the logical model? Can you elaborate on that?
    Philip

  • Update a primary key and Fk

    Hello
    I have to update a primary key (PK) which is referenced by many foreign keys (FK).
    The primary key columns cannot be updated as this would orphan the dependant tables,
    and the dependant tables cannot be updated prior to the parent table as this would also make them orphans.
    I think this problem was solved by disabling the foreign key constraints or deleting the original records and recreating them.
    Since neither of these solutions is particularly satisfactory for me I read about 'deferred constraints'.
    My question is:
    Can I use(modify to) 'INITIALLY DEFERRED' keyword on constraints's table already created with The default, INITIALLY IMMEDIATE ,
    that is, update my primary key and foreign keys, and then re-set to
    'INITIALLY IMMEDIATE'? Or another trick exists ?
    Thanks in advance for your attention

    It is very popular the idea that the updates on primary key columns are a very bad thing.
    Oracle supports this idea and that's why they don't give the "on update cascade" clause on foreign keys.
    So in this case I suggest you to define a master table like this.
    create table master_table (
         key_id number primary key,
         your_primary_key varchar2 not null unique
    /Then you must use that key_id column as foreign key in place of your original primary key. In this way don't even need to update referencing rows when updating the original primary key because the foreign key value doesn't change and everything is always fine as before.
    So instead to lose time implementing some strange sort of cascade triggers plain to do something like this on your schema.
    insert into master_table (id_key,primary_key) (
         select rownum,primary_key
         from your_main_table
    alter table your_main_table add (
         id_key number,
    update your_main_table a
    set id_key = (
              select b.id_key
              from master_table
              where b.primary_key=a.primary_key
         Drops foreign keys
    alter table your_main_table drop primary key cascade
    alter table your_main_table add constraint pk
         primary key(id_key)
    alter table your_main_table add constraint fk
         foreign key(id_key) references master_table
    alter table your_main_table drop (
         your_primary_key
    alter table a_referencing_table add (
         id_key number,
    update a_referencing_table a
    set id_key = (
              select b.id_key
              from master_table
              where b.primary_key=a.primary_key
    alter table a_referencing_table add constraint fk_2
         foreign key(id_key) references master_table
    alter table a_referencing_table drop (
         your_primary_key
    /If you have many objects referencing those tables I suggest you to rename the tables and to create views with the original name of the renamed tables that show data as it was before with a join on master_table. in this way you don't need to change the code of the application referencing them but you just need to recompile invalidated objects.
    Bye Alessandro

Maybe you are looking for

  • Classification set up for Vendor Master

    I plan on using Classifications for Vendors to assign a status.  I need to define the Class and assign to Class type as well as define the Characteristics and assign the values.  Can anyone tell me where this is done? Any help is appreciated. Thanks

  • OTN Virtual Developer Day – Web, Mobile and Beyond

    Hi, Are the recent ADF virtual developer day sessions still available?  I can no longer access them from the following URL:https://oracle.6connex.com/portal/ADF2013/login Thanks in Anticipation, Amar

  • Why procedure created with compilation errors?

    CREATE or REPLACE PROCEDURE AddStudent( p_stuID number, p_lname varchar2(30), p_fname varchar2(20), p_major varchar2(5) check(major IN ('ACCT','ECT','EET','BIS','BSIT','CIS','TCOM')), P_standing varchar2(10) check(standing IN ('FRESHMAN','SOPHOMORE',

  • RAW COMPRESSION

    hi guys not really an aperture question, however this might be the perfect audience to ask this question... do compressed raw files (such as from a nikon d70s) have less quality than uncompressed raw files? or is it a lossless compression without inf

  • Can you track source of clicks on the "clickable" icons

    Can you track source of clicks on the "clickable" icons or track links in Dreamweaver?  I know about Google analytics for a page body but don't know for clicks. Thanks in advance