Skip to Main Content
  • Questions
  • Regarding adding a column to existing table as key column

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Girish.

Asked: September 20, 2005 - 1:29 am UTC

Last updated: April 28, 2006 - 12:45 pm UTC

Version: 9.2.0.6.0

Viewed 1000+ times

You Asked

Hi Tom,

Here we have a requirement to be done in production database
Our current table structure is something below this

CREATE TABLE &owner..madnog_p_traff_isp_hour
(
subnetwork_id NUMBER not null,
ggsn_id VARCHAR2(100) not null,
funct_id VARCHAR2(10) not null,
isp_id VARCHAR2(10) not null,
period_start_time DATE not null,
period_duration number,
DISCDATAPKT number,
IDATOCTBLOW number,
ODATOCTBLOW number,
IERRINDMSG number,
OERRINDMSG number
) TABLESPACE &tablespace;

All columns that is ,

subnetwork_id NUMBER not null,
ggsn_id VARCHAR2(100) not null,
funct_id VARCHAR2(10) not null,
isp_id VARCHAR2(10) not null

are part of composite primary key and table contains data and now we want to add another column which should be part of composite primary key that already exists ( also note the position of key column in below table definition), that means

CREATE TABLE &owner..madnog_p_traff_isp_hour
(
subnetwork_id NUMBER not null,
ggsn_id VARCHAR2(100) not null,
***node_id VARCHAR2(100) not null, ****
funct_id VARCHAR2(10) not null,
isp_id VARCHAR2(10) not null,
period_start_time DATE not null,
period_duration number,
DISCDATAPKT number,
IDATOCTBLOW number,
ODATOCTBLOW number,
IERRINDMSG number,
OERRINDMSG number
) TABLESPACE &tablespace;

Is it possible for a table that already contains huge data

If so please let us know

Waiting for your reply

Thanks



and Tom said...

If this must be done "online" without significant down time (short locks taken at the very begin and end of this process), then you can use dbms_redefintion.

Else, you would stop modifications, create a new table selecting the default value for this node column you are adding, index, grant, constrain, whatever this new table, drop old and rename the new one.

Because, adding that not-null new column would otherwise perform an UPDATE of every row in the table and you say it is "big", that'll be a really big operation.

Here we change the primary key from (object_id,object_name) to (object_id,object_name,owner) and owner is given a default value of 'XXXX'

ops$tkyte@ORA9IR2> create table t NOLOGGING
2 as
3 select object_id, object_name, created from all_objects;

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter table t add constraint t_pk primary key(object_id,object_name);

Table altered.

ops$tkyte@ORA9IR2> exec dbms_redefinition.can_redef_table( user, 'T' );

PL/SQL procedure successfully completed.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> create table t_interim
2 as
3 select object_id, object_name, owner, created
4 from all_objects
5 where 1=0;

Table created.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> declare
2 l_colmap varchar(512);
3 begin
4 l_colmap :=
5 'object_id,
6 object_name,
7 ''XXXX'' owner,
8 created ';
9
10 dbms_redefinition.start_redef_table
11 ( uname => user,
12 orig_table => 'T',
13 int_table => 'T_INTERIM',
14 col_mapping => l_colmap );
15 end;
16 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> alter table t_interim add constraint t_pk2 primary key(object_id,object_name,owner);

Table altered.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> begin
2 dbms_redefinition.sync_interim_table( user, 'T', 'T_INTERIM' );
3 end;
4 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA9IR2> begin
2 dbms_redefinition.finish_redef_table( user, 'T', 'T_INTERIM' );
3 end;
4 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> desc t
Name Null? Type
---------------------------------------- -------- ----------------------------
OBJECT_ID NOT NULL NUMBER
OBJECT_NAME NOT NULL VARCHAR2(30)
OWNER NOT NULL VARCHAR2(30)
CREATED NOT NULL DATE

ops$tkyte@ORA9IR2> desc t_interim
Name Null? Type
---------------------------------------- -------- ----------------------------
OBJECT_ID NOT NULL NUMBER
OBJECT_NAME NOT NULL VARCHAR2(30)
CREATED NOT NULL DATE

ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> drop table t_interim;

Table dropped.

ops$tkyte@ORA9IR2> drop table t;

Table dropped.


Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, September 22, 2005 - 2:02 am UTC

Excellent

DBMS_REDEFINTION and PL/SQL

JD, April 28, 2006 - 10:55 am UTC

Tom,

We have a five nines availability requirement for our application which uses PL/SQL to perform its DML. We will be using an Oracle 10.2 environment.

I have a few questions regarding DBMS_REDEFINITION and PL/SQL objects (packages, procedures) that are dependent on the table being modified through the online redefinition.

As an example, I need to add a column to a table. This column also needs to be added to the corresponding PL/SQL routine for DML operations. I would like to use DBMS_REDEFINITION to minimize my downtime.

1. I am assuming that the existing PL/SQL object referencing the table would become invalid during the online redefinition, correct?

2. If this is the case, I would also assume that the new PL/SQL object reflecting the new column being added would need to be loaded after the redefinition, or can it be included as part of the redefintion?

Thanks for your help in advance.

Tom Kyte
April 28, 2006 - 12:45 pm UTC

1) after the redefine is complete - yes.

2) it would be after the redef

Other options

JD, May 02, 2006 - 5:15 pm UTC

Tom thanks for the feedback, however if we're in a five nines environment using PL/SQL for DML operations, the time to implement the change, recompile the stored procedure and restart the application may take take 30-45 seconds.

With only ~5 minutes of downtime a year, the ability to apply schema changes would be very limited. This doesn't even get into version upgrades (though a Logical Standby rolling upgrade may address this dependent on datatype support)

Are there any other suggestions you may be able to provide on how to apply schema changes when working in this type of environment?

Thanks

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library