We’re getting much closer to having Oracle SQL Developer version 4.1 ready for release – which includes SQLcl, our new command-line interface for Oracle Database.
Just a quick reminder in case you’re too lazy to click to that other post:
We’ve taken our existing Java based SQL*Plus script engine from SQL Developer, and built a new command line interface that does most of what SQL*Plus offers plus adds a bunch of cool GUI features from SQL Developer. We’re calling this new program, SQLcl.
One of the new commands is DDL.
SQL> ddl hr.employees CREATE TABLE "HR"."EMPLOYEES" ( "EMPLOYEE_ID" NUMBER(6,0), "FIRST_NAME" VARCHAR2(20), "LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE, "EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE, "PHONE_NUMBER" VARCHAR2(20), "HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE, "JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE, "SALARY" NUMBER(8,2), "COMMISSION_PCT" NUMBER(2,2), "MANAGER_ID" NUMBER(6,0), "DEPARTMENT_ID" NUMBER(4,0), CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE, CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" ENABLE, CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" ENABLE, CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID") REFERENCES "HR"."DEPARTMENTS" ("DEPARTMENT_ID") ENABLE, CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID") REFERENCES "HR"."JOBS" ("JOB_ID") ENABLE, CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID") REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE ) SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "USERS" COMMENT ON COLUMN "HR"."EMPLOYEES"."EMPLOYEE_ID" IS 'Primary key of employees table.' COMMENT ON COLUMN "HR"."EMPLOYEES"."FIRST_NAME" IS 'First name of the employee. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."LAST_NAME" IS 'Last name of the employee. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS 'Email id of the employee' COMMENT ON COLUMN "HR"."EMPLOYEES"."PHONE_NUMBER" IS 'Phone number of the employee; includes country code and area code' COMMENT ON COLUMN "HR"."EMPLOYEES"."HIRE_DATE" IS 'Date when the employee started on this job. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."JOB_ID" IS 'Current job of the employee; foreign key to job_id column of the jobs table. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."SALARY" IS 'Monthly salary of the employee. Must be greater than zero (enforced by constraint emp_salary_min)' COMMENT ON COLUMN "HR"."EMPLOYEES"."COMMISSION_PCT" IS 'Commission percentage of the employee; Only employees in sales department elgible for commission percentage' COMMENT ON COLUMN "HR"."EMPLOYEES"."MANAGER_ID" IS 'Manager id of the employee; has same domain as manager_id in departments table. Foreign key to employee_id column of employees table. (useful for reflexive joins and CONNECT BY query)' COMMENT ON COLUMN "HR"."EMPLOYEES"."DEPARTMENT_ID" IS 'Department id where employee works; foreign key to department_id column of the departments table' COMMENT ON TABLE "HR"."EMPLOYEES" IS 'employees table. Contains 107 rows. References with departments, jobs, job_history tables. Contains a self reference.' CREATE INDEX "HR"."EMP_DEPARTMENT_IX" ON "HR"."EMPLOYEES" ("DEPARTMENT_ID") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" CREATE INDEX "HR"."EMP_JOB_IX" ON "HR"."EMPLOYEES" ("JOB_ID") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" CREATE INDEX "HR"."EMP_MANAGER_IX" ON "HR"."EMPLOYEES" ("MANAGER_ID") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" CREATE INDEX "HR"."EMP_NAME_IX" ON "HR"."EMPLOYEES" ("LAST_NAME", "FIRST_NAME") PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS TABLESPACE "USERS" CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."UPDATE_JOB_HISTORY" AFTER UPDATE OF job_id, department_id ON employees FOR EACH ROW BEGIN add_job_history(:OLD.employee_id, :OLD.hire_date, sysdate, :OLD.job_id, :OLD.department_id); END; ALTER TRIGGER "HR"."UPDATE_JOB_HISTORY" ENABLE CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."SECURE_EMPLOYEES" BEFORE INSERT OR UPDATE OR DELETE ON employees BEGIN secure_dml; END secure_employees; ALTER TRIGGER "HR"."SECURE_EMPLOYEES" DISABLE
Woohoo! But I don’t need that icky STORAGE stuff
So turn it off.
We’re calling DBMS_METADATA under the covers to generate this DDL. And you can tell that package exactly how you want your DDL generated. The command is pretty simple, but it’s a bit verbose for me to type, much less to remember.
So I created my own command to toggle this on and off. Well, two commands to be honest.
How do you create your own ‘commands?’ Use the ALIAS feature.
ALIAS new_commmand=code
You can feed one or more parameters to your command, and you can execute one or more statements. Mine are very simple.
SQL> dd_storage_off Command=dd_storage_off PL/SQL PROCEDURE successfully completed. SQL> ddl hr.employees CREATE TABLE "HR"."EMPLOYEES" ( "EMPLOYEE_ID" NUMBER(6,0), "FIRST_NAME" VARCHAR2(20), "LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE, "EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE, "PHONE_NUMBER" VARCHAR2(20), "HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE, "JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE, "SALARY" NUMBER(8,2), "COMMISSION_PCT" NUMBER(2,2), "MANAGER_ID" NUMBER(6,0), "DEPARTMENT_ID" NUMBER(4,0), CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE, CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL") USING INDEX ENABLE, CONSTRAINT "EMP_EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID") USING INDEX ENABLE, CONSTRAINT "EMP_DEPT_FK" FOREIGN KEY ("DEPARTMENT_ID") REFERENCES "HR"."DEPARTMENTS" ("DEPARTMENT_ID") ENABLE, CONSTRAINT "EMP_JOB_FK" FOREIGN KEY ("JOB_ID") REFERENCES "HR"."JOBS" ("JOB_ID") ENABLE, CONSTRAINT "EMP_MANAGER_FK" FOREIGN KEY ("MANAGER_ID") REFERENCES "HR"."EMPLOYEES" ("EMPLOYEE_ID") ENABLE ) COMMENT ON COLUMN "HR"."EMPLOYEES"."EMPLOYEE_ID" IS 'Primary key of employees table.' COMMENT ON COLUMN "HR"."EMPLOYEES"."FIRST_NAME" IS 'First name of the employee. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."LAST_NAME" IS 'Last name of the employee. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."EMAIL" IS 'Email id of the employee' COMMENT ON COLUMN "HR"."EMPLOYEES"."PHONE_NUMBER" IS 'Phone number of the employee; includes country code and are COMMENT ON COLUMN "HR"."EMPLOYEES"."HIRE_DATE" IS 'DATE WHEN the employee started ON this job. A NOT NULL COLUMN. COMMENT ON COLUMN "HR"."EMPLOYEES"."JOB_ID" IS 'Current job of the employee; foreign key to job_id column of the jobs table. A not null column.' COMMENT ON COLUMN "HR"."EMPLOYEES"."SALARY" IS 'Monthly salary of the employee. Must be greater than zero (enforced by constraint emp_salary_min)' COMMENT ON COLUMN "HR"."EMPLOYEES"."COMMISSION_PCT" IS 'Commission percentage of the employee; Only employees in department elgible for commission percentage' COMMENT ON COLUMN "HR"."EMPLOYEES"."MANAGER_ID" IS 'Manager id of the employee; has same domain as manager_id in departments table. Foreign key to employee_id column of employees table. (useful for reflexive joins and CONNECT BY query)' COMMENT ON COLUMN "HR"."EMPLOYEES"."DEPARTMENT_ID" IS 'Department id where employee works; foreign key to departm column of the departments table' COMMENT ON TABLE "HR"."EMPLOYEES" IS 'employees table. Contains 107 rows. References with departments, jobs, job_history tables. Contains a self reference.' CREATE INDEX "HR"."EMP_DEPARTMENT_IX" ON "HR"."EMPLOYEES" ("DEPARTMENT_ID") CREATE INDEX "HR"."EMP_JOB_IX" ON "HR"."EMPLOYEES" ("JOB_ID") CREATE INDEX "HR"."EMP_MANAGER_IX" ON "HR"."EMPLOYEES" ("MANAGER_ID") CREATE INDEX "HR"."EMP_NAME_IX" ON "HR"."EMPLOYEES" ("LAST_NAME", "FIRST_NAME") CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."UPDATE_JOB_HISTORY" AFTER UPDATE OF job_id, department_id ON employees FOR EACH ROW BEGIN add_job_history(:OLD.employee_id, :OLD.hire_date, sysdate, :OLD.job_id, :OLD.department_id); END; ALTER TRIGGER "HR"."UPDATE_JOB_HISTORY" ENABLE CREATE OR REPLACE EDITIONABLE TRIGGER "HR"."SECURE_EMPLOYEES" BEFORE INSERT OR UPDATE OR DELETE ON employees BEGIN secure_dml; END secure_employees; ALTER TRIGGER "HR"."SECURE_EMPLOYEES" DISABLE SQL>
You can find all of the TRANSFORM procedure options here for defining how you want your DDL generated.
And of COURSE we support spool, so if I want a script file of a table without storage parameters, I just run…
dd_storage_off spool c:\scripts\employeees_no_storage.sql ddl hr.employees spool off dd_storage_on