Skip to Main Content
  • Questions
  • Getting Foreign and Primary Key syntax from the Database

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Sundar.

Asked: January 24, 2003 - 8:37 am UTC

Last updated: September 03, 2009 - 7:51 am UTC

Version: 9.2.0

Viewed 10K+ times! This question is

You Asked

Hai Tom,
Need your help in getting the following syntax. This is the example output which I would like to use for my Database Tables. Are there any built in procedures to be used if so what are they and how to use them. Can this data be retrived from any table of any of the users in the Database. We are using 9i Version Database.

USER_DEPENDENCIES IS NOT GIVING THE INFORMATION FOR TABLES.

ALTER TABLE EMP ADD
(CONSTRAINT PK_EMP PRIMARY KEY (EMPNO))
/
ALTER TABLE EMP ADD
(CONSTRAINT FK_DEPTNO FOREIGN KEY (DEPTNO)
REFERENCES DEPT (DEPTNO))
/
Regards
Sundar


and Tom said...

user_constraints would be the place I would look for constraints. user_dependencies -- well, that I would use to see who relies on who.


But, anyway, you mean like this:

ops$tkyte@ORA920> begin
2 dbms_metadata.set_transform_param
3 ( DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', true );
4 dbms_metadata.set_transform_param
5 ( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false );
6 dbms_metadata.set_transform_param
7 ( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE );
8 end;
9 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA920>
ops$tkyte@ORA920> select dbms_metadata.get_ddl( 'TABLE', 'EMP' ) from dual;

DBMS_METADATA.GET_DDL('TABLE','EMP')
--------------------------------------------------------------------------------

CREATE TABLE "OPS$TKYTE"."EMP"
( "EMPNO" NUMBER(*,0),
"MGR" NUMBER(*,0)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE "USERS" ;
CREATE UNIQUE INDEX "OPS$TKYTE"."EMP_PK" ON "OPS$TKYTE"."EMP" ("EMPNO")
PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE "USERS" ;
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_PK" PRIMARY KEY ("EMPNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE "USERS" ENABLE;
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_FK_EMP" FOREIGN KEY ("MGR")
REFERENCES "OPS$TKYTE"."EMP" ("EMPNO") ENABLE;





Rating

  (25 ratings)

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

Comments

Getting Foreign and Primary Key syntax from the Database

sundar anupindi, January 24, 2003 - 10:49 pm UTC

This is very useful for getting the Reveser Enginnering of the database with this I would like to generate the syntax for the creation of the table in the MySql Database.

Renu Gharpue, January 29, 2003 - 2:25 pm UTC

CREATE TABLE "OPS$TKYTE"."EMP"
( "EMPNO" NUMBER(*,0),
"MGR" NUMBER(*,0)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE "USERS" ;
CREATE UNIQUE INDEX "OPS$TKYTE"."EMP_PK" ON "OPS$TKYTE"."EMP" ("EMPNO")
PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE "USERS" ;
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_PK" PRIMARY KEY ("EMPNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
TABLESPACE "USERS" ENABLE;
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_FK_EMP" FOREIGN KEY ("MGR")
REFERENCES "OPS$TKYTE"."EMP" ("EMPNO") ENABLE;
For me breaks words
like
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_
FK_EMP" FOREIGN KEY ("MGR")
REFERENCES "OPS$TKYTE"."EMP" ("EMPNO") ENABLE;
How can this be avoided?
eg breaking of "EMP_FK_EMP"
into "EMP_ and FK_EMP" FOREIGN KEY ("MGR") in next line.
.. thnaks
.. Renu

Tom Kyte
January 29, 2003 - 3:39 pm UTC

just use the typical SQL Plus formatting commands then:
<b>
ops$tkyte@ORA920> column x format a20 WORD_WRAPPED</b>
ops$tkyte@ORA920> select dbms_metadata.get_ddl( 'TABLE', 'EMP' ) x from dual;

X
--------------------
CREATE TABLE
"OPS$TKYTE"."EMP"
(       "EMPNO"
NUMBER(4,0) NOT NULL
ENABLE,
"ENAME"
VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0)
) PCTFREE 10 PCTUSED
40 INITRANS 1
MAXTRANS 255
NOCOMPRESS LOGGING
TABLESPACE "USERS" ;


<b>
ops$tkyte@ORA920> column x format a80 WORD_WRAPPED</b>
ops$tkyte@ORA920> select dbms_metadata.get_ddl( 'TABLE', 'EMP' ) x from dual;

X
--------------------------------------------------------------------------------
CREATE TABLE "OPS$TKYTE"."EMP"
(       "EMPNO" NUMBER(4,0) NOT NULL ENABLE,
"ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
TABLESPACE "USERS" ;


 

ddl tracking

mo, January 29, 2003 - 4:53 pm UTC

Tom:

1. is dbms_metadata a separate package that I have to install to test the above?

2. is it used to track everything that was done for a table?


Tom Kyte
January 30, 2003 - 8:01 am UTC

1) nope, you just need to install Oracle9i

2) it extracts the ddl from the data dictionary. it keeps track of nothing, it just reports on what is there.

kumar s b, January 30, 2003 - 12:13 am UTC

I believe this package (dbms_metadata) is introduced in 9i. Is there any method to generate a similar code in 8i?

Tom Kyte
January 30, 2003 - 8:48 am UTC

$ exp userid=scott/tiger tables=emp

Export: Release 8.1.7.4.0 - Production on Thu Jan 30 08:47:40 2003

(c) Copyright 2000 Oracle Corporation. All rights reserved.


Connected to: Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production
With the Partitioning option
JServer Release 8.1.7.4.0 - Production
Export done in WE8ISO8859P1 character set and WE8ISO8859P1 NCHAR character set

About to export specified tables via Conventional Path ...
. . exporting table EMP 14 rows exported
Export terminated successfully without warnings.

$ imp userid=scott/tiger full=y indexfile=emp.sql

Import: Release 8.1.7.4.0 - Production on Thu Jan 30 08:47:48 2003

(c) Copyright 2000 Oracle Corporation. All rights reserved.


Connected to: Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production
With the Partitioning option
JServer Release 8.1.7.4.0 - Production

Export file created by EXPORT:V08.01.07 via conventional path
import done in WE8ISO8859P1 character set and WE8ISO8859P1 NCHAR character set
. . skipping table "EMP"

Import terminated successfully without warnings.

$ cat emp.sql

REM CREATE TABLE "SCOTT"."EMP" ("EMPNO" NUMBER(4, 0) NOT NULL ENABLE,
REM "ENAME" VARCHAR2(10), "MGR" NUMBER(4, 0), "HIREDATE" DATE, "SAL"
REM NUMBER(7, 2), "COMM" NUMBER(7, 2), "DEPTNO" NUMBER(2, 0), "JOB"
REM VARCHAR2(10)) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING
REM STORAGE(INITIAL 16384 NEXT 16384 MINEXTENTS 1 MAXEXTENTS 2147483645
REM PCTINCREASE 10 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
REM TABLESPACE "SYSTEM" ;
REM ... 14 rows


DDL

mo, January 30, 2003 - 11:30 am UTC

great way of getting table info in 8i.

dbms_metadata.get_ddl only shows first 2 columns

ht, August 29, 2003 - 6:38 pm UTC

Hi Tom,
Which sqlplus setting do I need to set to view the entire scott.emp table?

TIA
ht

select dbms_metadata.get_ddl( 'TABLE','EMP','SCOTT' ) x from dual
2 ;

X
--------------------------------------------------------------------------------

CREATE TABLE "SCOTT"."EMP"
( "EMPNO" NUMBER(4,0),
"ENAME" VARCHAR2(10),


1 row selected.

select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production
PL/SQL Release 9.2.0.3.0 - Production
CORE 9.2.0.3.0 Production
TNS for Solaris: Version 9.2.0.3.0 - Production
NLSRTL Version 9.2.0.3.0 - Production

5 rows selected.

desc scott.emp;
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)


Tom Kyte
August 30, 2003 - 10:30 am UTC

SQL> set long 50000 

Thanks.

ht, September 05, 2003 - 1:49 pm UTC


its 8.1.7 i will use it for 9i -- Thanks

A reader, March 26, 2004 - 1:08 pm UTC


Using transforms in get_ddl()?

A reader, September 09, 2004 - 10:41 am UTC

The docs say that

DBMS_METADATA.GET_XML (
object_type IN VARCHAR2,
name IN VARCHAR2,
schema IN VARCHAR2 DEFAULT NULL,
version IN VARCHAR2 DEFAULT 'COMPATIBLE',
model IN VARCHAR2 DEFAULT 'ORACLE',
transform IN VARCHAR2 DEFAULT NULL)
RETURN CLOB;

transform: The name of a transformation on the output. This parameter takes the same values as the ADD_TRANSFORM name parameter.

How can I specify the transforms in the get_ddl() call itself? I tried

select dbms_metadata.get_ddl('TABLE','EMP',null,'COMPATIBLE','ORACLE','storage=false') from dual;

But got an error

Thanks

Tom Kyte
September 09, 2004 - 11:46 am UTC

that's not the way it works -- the name to "add_transform" could be DDL to change the default named transform called "DDL"

use the working technique demonstrated above in the original answer.

get_granted_ddl() error

A reader, September 09, 2004 - 11:50 am UTC

select dbms_metadata.get_granted_ddl('TABLE') from dual;

ERROR:
ORA-31600: invalid input value GRANTEE for parameter NAME in function
SET_FILTER
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 105
ORA-06512: at "SYS.DBMS_METADATA_INT", line 1980
ORA-06512: at "SYS.DBMS_METADATA_INT", line 3665
ORA-06512: at "SYS.DBMS_METADATA", line 670
ORA-06512: at "SYS.DBMS_METADATA", line 597
ORA-06512: at "SYS.DBMS_METADATA", line 1339
ORA-06512: at line 1

Is it me or is it a bug in 9.2.0.4?

Thanks

Tom Kyte
September 09, 2004 - 12:47 pm UTC

not sure, it works with some inputs -- like SYSTEM_GRANT, but not all.

I'll refer you to support on this one. i do not see anything reported against it.

How to eliminate schema Name

A reader, September 09, 2004 - 3:08 pm UTC

Is there any way to get the script without the hard coded schema name qualified in dbms_metadata package

Though I can do a quick search/replace on final script still ?

Extracting only FOREIGN KEYs DDL using dbms_metadata

Shimon Tourgeman, March 15, 2005 - 8:19 am UTC

Dear Tom,
I've searched this site to find a way to use DBMS_METADATA.GET_DDL in order to get ONLY a FOREIGN KEY ddl.
I used the following code to get PRIMARY KEY ddls:

create or replace function fn_get_PKFK_ddl (i_constraint_name in varchar2 )
return clob
is

h number;
o_constraint_ddl       varchar2(32760);

begin
     h:=dbms_metadata.open('CONSTRAINT');
     dbms_metadata.set_transform_param (DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', true );
     dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE', false );
     dbms_metadata.set_transform_param( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', TRUE );
     o_constraint_ddl:=DBMS_METADATA.GET_DDL('CONSTRAINT' ,i_constraint_name); 
     dbms_metadata.close(h);

     return (o_constraint_ddl) ;

end  fn_get_PKFK_ddl  ;


SQL> select fn_get_PKFK_ddl ('PK_DEPT') from dual;

Which Gives:

  ALTER TABLE "SCOTT"."DEPT" ADD CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)   TABLESPACE "SYSTEM"  ENABLE ;
 
and that's nice.


How do I get a FOREIGN KEY DDL?

Thanks in advance,
Shimon Tourgeman.
 

Tom Kyte
March 15, 2005 - 8:49 am UTC

ops$tkyte@ORA9IR2> create table dept as select * from scott.dept;
 
Table created.
 
ops$tkyte@ORA9IR2> alter table dept add constraint dept_pk primary key(deptno);
 
Table altered.
 
ops$tkyte@ORA9IR2> create table emp as select * from scott.emp;
 
Table created.
 
ops$tkyte@ORA9IR2> alter table emp add constraint emp_pk primary key(empno);
 
Table altered.
 
ops$tkyte@ORA9IR2> alter table emp add constraint emp_emp_fk foreign key (mgr) references emp(empno);
 
Table altered.
 
ops$tkyte@ORA9IR2> alter table emp add constraint emp_dept_fk foreign key (deptno) references dept(deptno);
 
Table altered.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> column text format a80 word_wrapped;
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select dbms_metadata.get_dependent_ddl( 'REF_CONSTRAINT', 'EMP' ) text
  2    from dual;
 
TEXT
-------------------------------------------------------------------------------
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_EMP_FK" FOREIGN KEY ("MGR")
REFERENCES "OPS$TKYTE"."EMP" ("EMPNO") ENABLE
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY
("DEPTNO")
REFERENCES "OPS$TKYTE"."DEPT" ("DEPTNO") ENABLE
 
 

Thank you very much !

Shimon Tourgeman., March 16, 2005 - 2:54 am UTC

You saved my package...

BTW: I think Oracle would better do if "refining" the documentation of DBMS_METADATA utility.
Using it, I've developed a package which convert a given database schema to use a whole new naming conventions.
I use the package and Oracle dictionary tables.

Again- Thank You.

dbms_metadata examples

MaryamT, May 18, 2005 - 1:07 pm UTC

Excellent examples!

Great Examples but if I don't know the name of child table?

F.T, May 18, 2005 - 1:11 pm UTC

How do I find the FK constraint DDL if I don't know the child table's name. In the case of dept and emp tables. If I only knew dept but had no idea that emp existed yet I need to rebuild any FK relationship that existed between an unknown table and dept? How do I find the name of tables which are dependent on dept?

Metadata for finding child tables

F.T, May 18, 2005 - 1:40 pm UTC

Thanks again for a great follow up, Tom!
As always you're most resourceful!


A reader, March 10, 2006 - 6:37 pm UTC

NCRMST3:SQL>desc e
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                     NOT NULL NUMBER(4)
 ENAME                                              VARCHAR2(10)
 JOB                                                VARCHAR2(9)
 MGR                                                NUMBER(4)
 HIREDATE                                           DATE
 SAL                                                NUMBER(7,2)
 COMM                                               NUMBER(7,2)
 DEPTNO                                             NUMBER(2)

NCRMST3:SQL>alter table e modify sal not null;

Table altered.

NCRMST3:SQL>desc e
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO                                     NOT NULL NUMBER(4)
 ENAME                                              VARCHAR2(10)
 JOB                                                VARCHAR2(9)
 MGR                                                NUMBER(4)
 HIREDATE                                           DATE
 SAL                                       NOT NULL NUMBER(7,2)
 COMM                                               NUMBER(7,2)
 DEPTNO                                             NUMBER(2)

NCRMST3:SQL>begin
dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS'  2  ,true);
dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS',true);
  3    4  dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS_AS_ALTER', true);
  5  dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE',false);
dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATO  6  R',true);
end;
  7    8  /

PL/SQL procedure successfully completed.

NCRMST3:SQL>select dbms_metadata.get_ddl('TABLE','E') from dual;

DBMS_METADATA.GET_DDL('TABLE','E')
--------------------------------------------------------------------------------

  CREATE TABLE "SCOTT"."E"
   (    "EMPNO" NUMBER(4,0) NOT NULL ENABLE,
        "ENAME" VARCHAR2(10),
        "JOB" VARCHAR2(9),
        "MGR" NUMBER(4,0),
        "HIREDATE" DATE,
        "SAL" NUMBER(7,2) NOT NULL ENABLE,
        "COMM" NUMBER(7,2),
        "DEPTNO" NUMBER(2,0)
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  TABLESPACE "SYSTEM" ;


Why the not null constraint is not shown seperately as alter table e modify sal not null? Is there any way i can get not null constraints seperate like foreign keys?

Regards
Shailesh 

Tom Kyte
March 10, 2006 - 8:37 pm UTC

No, not null is a column constraint and will just come out that way. We cannot tell if you

a) created the table column not null
b) added it later



A bizarre requirements!

A reader, March 24, 2006 - 12:54 pm UTC

Tom,

Is it possible to know all the child of let's say table A that is being referenced by a fkey? I have been
searching in your web site and I can't find it.


thanks!



Tom Kyte
March 24, 2006 - 3:56 pm UTC

select * from user|all|dba_constraints
where r_constraint_name = 'PRIMARY KEY NAME OF PARENT OF INTEREST'
and r_owner = 'PARENT KEY CONSTRAINT OWNER'


More on dbms_metadata and FKs

Lucio, April 27, 2006 - 1:28 pm UTC

Tom:
You clearly showed how to get all the FKs DDL at once using:

select dbms_metadata.get_dependent_ddl ( 'REF_CONSTRAINT', 'EMP' ) text from dual;

TEXT
-------------------------------------------------------------------------------
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_EMP_FK" FOREIGN KEY ("MGR")
REFERENCES "OPS$TKYTE"."EMP" ("EMPNO") ENABLE
ALTER TABLE "OPS$TKYTE"."EMP" ADD CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY
("DEPTNO")
REFERENCES "OPS$TKYTE"."DEPT" ("DEPTNO") ENABLE

It returned all the FKs from the EMP table.

Is there any possibility to get only one particular FK constraint supplying its name?
I am programming some logic for each of the DDLs returned so I want to get them one by one.

As per I could read the get_dependent_ddl function and 'REF_CONSTRAINT' object type are only used with the table name to return all the FKs present.

Thanks in advance.


dbms_metadata - close but no cigar

ali, May 21, 2008 - 8:39 am UTC

I can't quite get the output I want with dbms_metadata.

I want table ddl to include 'not nulls',
but completely exclude:
pk and fk constraints,
tablespace,
segment,
storage

using the following transforms:
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'PRETTY',true);
exec dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM,'TABLESPACE',false);
exec dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
exec dbms_metadata.set_transform_param(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false);
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS',true);
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS_AS_ALTER',true);
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'REF_CONSTRAINTS',true);
exec DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);

The closest I can get to, is constraints as alter as part of the getddl for tables.

If I switch constraints = false, then I lose my not nulls, if I switch constraints_as_alter to false, then I get them as part of the table spec.

Is there a combination/another transform that I have missed?

ta

Constraint

Dilip, September 01, 2008 - 6:41 am UTC

Hi Tom,

All ur responses are very useful thanks

SQLTERMINATOR and ref_constraint

Lise, September 01, 2009 - 12:41 pm UTC

Hi,
I have a small issue when setting the sqlterminator to true and then attempting to extract metadata for a ref constraint.
This is my code:
BEGIN
dbms_metadata.set_transform_param(dbms_metadata.session_transform
,'SQLTERMINATOR'
,TRUE);

print_clob(dbms_metadata.get_ddl('REF_CONSTRAINT'
,'A_FK_KEY'));
END;

The output is as follows, but as you can see the semicolon is missing:

ALTER TABLE "DEV1"."TABLE1" ADD CONSTRAINT "A_FK_KEY" FOREIGN KEY ("COLUMN1")
REFERENCES "DEV1"."TABLE2" ("COLUMN1") ENABLE

I am using 9.2.0.5.0
Tom Kyte
September 01, 2009 - 5:43 pm UTC

ops$tkyte%ORA10GR2> create table t ( x int primary key, y int );

Table created.

ops$tkyte%ORA10GR2> alter table t add constraint a_fk_key foreign key(y) references t;

Table altered.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> BEGIN
  2      dbms_metadata.set_transform_param(dbms_metadata.session_transform
  3                                       ,'SQLTERMINATOR'
  4                                       ,TRUE);
  5
  6      dbms_output.put_line(dbms_metadata.get_ddl('REF_CONSTRAINT' ,'A_FK_KEY'));
  7  END;
  8  /

  ALTER TABLE "OPS$TKYTE"."T" ADD CONSTRAINT "A_FK_KEY" FOREIGN KEY ("Y")

REFERENCES "OPS$TKYTE"."T" ("X") ENABLE;


PL/SQL procedure successfully completed.


maybe it is your print_clob routine. I ran in 9i, 10g and 11g.

sqlterminator and ref_constraints

Lise, September 02, 2009 - 5:01 am UTC

Hi,
I replaced the print_clob with dbms_output.put_line, and rerun the statements. However, in 9i it still does not include the semicolon.
I have tried it on the 10g express installed, and it works there.

Here is a more detailed extract:
SQL> select * from v$instance;

INSTANCE_NUMBER INSTANCE_NAME
--------------- ----------------
HOST_NAME
----------------------------------------------------------------
VERSION           STARTUP_T STATUS       PAR    THREAD# ARCHIVE LOG_SWITCH_
----------------- --------- ------------ --- ---------- ------- -----------
LOGINS     SHU DATABASE_STATUS   INSTANCE_ROLE      ACTIVE_ST
---------- --- ----------------- ------------------ ---------
              1 LIFEDEV
gemini
9.2.0.5.0         30-AUG-09 OPEN         NO           1 STARTED
ALLOWED    NO  ACTIVE            PRIMARY_INSTANCE   NORMAL


SQL> BEGIN
  2      dbms_metadata.set_transform_param(dbms_metadata.session_transform
  3                                       ,'SQLTERMINATOR'
  4                                       ,TRUE);
  5  
  6      dbms_output.put_line((dbms_metadata.get_ddl('REF_CONSTRAINT'
  7                                      ,'FK2_HMRC_DATA')));
  8  END;
  9  /

  ALTER TABLE "LPARKER_DEV"."HMRC_DATA" ADD CONSTRAINT "FK2_HMRC_DATA" FOREIGN
KEY ("REPORT_HISTORY_ID")
          REFERENCES "LPARKER_DEV"."HMRC_REPORT_HISTORY"
("REPORT_HISTORY_ID") ENABLE


Tom Kyte
September 02, 2009 - 10:56 am UTC

it works in 9.2.0.8 fine, what is your exact release.

sqlterminator and ref constraints

Lise, September 02, 2009 - 12:25 pm UTC

I am using 9.2.0.5.0 so I am on the wrong version.

Just another quick question please in relation to dbms_metadata and the column/table comments.
If I have a comment like this: Client's surname
It is extracted like this:
'Client's surname'

This will fail the syntax check due to single quotes all over the place.
Do I ensure that the database do not contain single quotes for comments, or is there something else I can do to perhaps alter the extracted comment to this:
"Client's surname"

Thanks
Tom Kyte
September 02, 2009 - 1:02 pm UTC

give me an example to work with please

create a table, comment on it and demonstrate your issue.

Comments and single quotes

Lise, September 03, 2009 - 4:30 am UTC

Hi,
Here is a complete example run in 9.2.0.5.0.
SQL> CREATE TABLE test_column (col1 VARCHAR2(1));

Table created.

SQL> COMMENT ON COLUMN test_column.col1 IS 'Client''s address';

Comment created.

SQL> DECLARE
  2      ln_comment_handle       NUMBER;
  3      ln_comment_trans_handle NUMBER;
  4      lt_comment_ddls         sys.ku$_ddls;
  5  BEGIN
  6      ln_comment_handle       := dbms_metadata.OPEN(object_type => 'COMMENT');
  7      ln_comment_trans_handle := dbms_metadata.add_transform(handle => ln_comment_handle
  8                                                            ,NAME   => 'DDL');
  9  
 10      dbms_metadata.set_filter(handle => ln_comment_handle
 11                              ,NAME   => 'BASE_OBJECT_NAME'
 12                              ,VALUE  => 'TEST_COLUMN');
 13  
 14      lt_comment_ddls := dbms_metadata.fetch_ddl(ln_comment_handle);
 15      DBMS_OUTPUT.PUT_LINE('Got ' || lt_comment_ddls(1).ddltext);
 16  END;
 17  /
Got  COMMENT ON COLUMN "LPARKER_DEV"."TEST_COLUMN"."COL1" IS 'Client's address'


PL/SQL procedure successfully completed.

SQL> COMMENT ON COLUMN "LPARKER_DEV"."TEST_COLUMN"."COL1" IS 'Client's address'
  2  ;
ERROR:
ORA-01756: quoted string not properly terminated

Knowing my luck it is probably resolved in a later version.

Thanks

Tom Kyte
September 03, 2009 - 7:51 am UTC

funny how the stars seem to drop when I ask people for simple ways to reproduce their issues - yet this site is stuffed full with full examples from start to finish from me - so you can reproduce or not what I saw...

anyway

ops$tkyte%ORA9IR2> CREATE TABLE test_column (col1 VARCHAR2(1));

Table created.

ops$tkyte%ORA9IR2> COMMENT ON COLUMN test_column.col1 IS 'Client''s address';

Comment created.

ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> DECLARE
  2      ln_comment_handle       NUMBER;
  3      ln_comment_trans_handle NUMBER;
  4      lt_comment_ddls         sys.ku$_ddls;
  5  BEGIN
  6      ln_comment_handle       := dbms_metadata.OPEN(object_type => 'COMMENT');
  7      ln_comment_trans_handle := dbms_metadata.add_transform(handle => ln_comment_handle
  8                                                            ,NAME   => 'DDL');
  9
 10      dbms_metadata.set_filter(handle => ln_comment_handle
 11                              ,NAME   => 'BASE_OBJECT_NAME'
 12                              ,VALUE  => 'TEST_COLUMN');
 13
 14      lt_comment_ddls := dbms_metadata.fetch_ddl(ln_comment_handle);
 15      DBMS_OUTPUT.PUT_LINE('Got ' || lt_comment_ddls(1).ddltext);
 16  END;
 17  /
Got  COMMENT ON COLUMN "OPS$TKYTE"."TEST_COLUMN"."COL1" IS 'Client''s address'


PL/SQL procedure successfully completed.

ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
PL/SQL Release 9.2.0.8.0 - Production
CORE    9.2.0.8.0       Production
TNS for Linux: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production

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