CREATE OR REPLACE PROCEDURE P_DUP_DEL_CREATE_TAB IS
BEGIN
CREATE OR REPLACE TABLE T_DUPLICATE_TABLE (
F_NUMBER NUMBER(2),
S_NUMBER NUMBER(1),
CONSTRAINT ID PRIMARY KEY (F_NUMBER, S_NUMBER)
);
END P_DUP_DEL_CREATE_TAB;
I don't know why it gives me this error:
Error(3,3): PLS-00103: Found the symbol "CREATE" instead of one of the following: ( begin case declare exit for goto if ...
I tried using the backslash, but it doesn't solve the problem, any help?
You cannot use DDL statements in PL/SQL. You need to use EXECUTE IMMEDIATE and cannot use CREATE OR REPLACE:
CREATE OR REPLACE PROCEDURE P_DUP_DEL_CREATE_TAB
IS
TABLE_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942);
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE T_DUPLICATE_TABLE';
EXCEPTION
WHEN TABLE_DOES_NOT_EXIST THEN
EXECUTE IMMEDIATE 'CREATE TABLE T_DUPLICATE_TABLE (
F_NUMBER NUMBER(2),
S_NUMBER NUMBER(1),
CONSTRAINT ID PRIMARY KEY (F_NUMBER, S_NUMBER)
)';
END P_DUP_DEL_CREATE_TAB;
/
db<>fiddle here
Related
I am trying to create a table in Oracle DB and I am getting this error:
PLS-00103: Encountered the symbol "(" when expecting one of the following:
. , # in <an identifier>
<a double-quoted delimited-identifier> partition subpartition
The create statement is the following:
set echo on
set term on
set pause off
set pages 5000
set serveroutput on size 99999
spool sqlResult.lst
declare
--
wcont number :=0;
begin
CREATE TABLE schema.TABLE
(ID NUMBER GENERATED BY DEFAULT AS IDENTITY,
DOCUMENT1 VARCHAR2(50),
DOCUMENT2 VARCHAR2(50),
ID_CLIENT1 NUMBER,
ID_CLIENT2 NUMBER,
BDATEO DATE,
FDATE DATE,
ID_PROCESS VARCHAR2(100),
TYPE VARCHAR2(50),
CONSTRAINT tmp_pk PRIMARY KEY(ID));
wcont:=wcont+ sql%ROWCOUNT;
if sql%ROWCOUNT > 1
then
RAISE_APPLICATION_ERROR(-20010,'ERROR');
end if;
--
commit;
--
dbms_output.put_line('SUCCESS');
--
exception
when others then
rollback;
dbms_output.put_line(sqlerrm);
end;
/
spool off
exit
I can't see where is the error because the only "(" are after new table name and I think it's mandatory.
Best regards!
I want to see the query used to create the table DOCTORS in SQL Developer with
SELECT dbms_metadata.get_ddl('TABLE', 'DOCTORS')
FROM dual;
Then it shows only part of the query.
DBMS_METADATA.GET_DDL('TABLE','DOCTORS')
--------------------------------------------------------------------------------
CREATE TABLE "C##AKIRA"."DOCTORS"
( "CODED" NUMBER(2,0),
"NAMED" VARCHA
I suspect this is due to some displaying setting. Could you please elaborate on how to show the full result?
-- Drop tables if they already exist
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE works_in';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE depends';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE wards';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE doctors';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
-- Create the doctors database
CREATE TABLE doctors (
coded NUMBER(2),
named VARCHAR2(15),
speciald NUMBER(2),
PRIMARY KEY (coded)
);
CREATE TABLE wards (
codew NUMBER(2),
namew VARCHAR2(15),
coded NUMBER(2),
PRIMARY KEY(codew),
FOREIGN KEY (coded) REFERENCES doctors (coded)
);
CREATE TABLE works_in (
coded NUMBER(2),
codew NUMBER(2),
datewi DATE,
hourcount NUMBER(2),
PRIMARY KEY (coded, codew, datewi),
FOREIGN KEY (coded) REFERENCES doctors (coded),
FOREIGN KEY (codew) REFERENCES wards (codew)
);
CREATE TABLE depends (
codew_parent NUMBER(2),
codew_child NUMBER(2),
PRIMARY KEY (codew_parent, codew_child),
FOREIGN KEY (codew_parent) REFERENCES wards (codew),
FOREIGN KEY (codew_child) REFERENCES wards (codew)
);
-- Show the schema of a table
SELECT dbms_metadata.get_ddl('TABLE', 'DOCTORS')
FROM dual;
try putting
set long 1000000 longc 100000 pages 10000
before the select dbms_metadata....
It tells sqldev (and sqlplus/sqlcl also) to fetch 1MB of data and not put headers until after 10000 lines
I would like to add a constraint that will check values from related table.
I have 3 tables:
CREATE TABLE somethink_usr_rel (
user_id BIGINT NOT NULL,
stomethink_id BIGINT NOT NULL
);
CREATE TABLE usr (
id BIGINT NOT NULL,
role_id BIGINT NOT NULL
);
CREATE TABLE role (
id BIGINT NOT NULL,
type BIGINT NOT NULL
);
(If you want me to put constraint with FK let me know.)
I want to add a constraint to somethink_usr_rel that checks type in role ("two tables away"), e.g.:
ALTER TABLE somethink_usr_rel
ADD CONSTRAINT CH_sm_usr_type_check
CHECK (usr.role.type = 'SOME_ENUM');
I tried to do this with JOINs but didn't succeed. Any idea how to achieve it?
CHECK constraints cannot currently reference other tables. The manual:
Currently, CHECK expressions cannot contain subqueries nor refer to
variables other than columns of the current row.
One way is to use a trigger like demonstrated by #Wolph.
A clean solution without triggers: add redundant columns and include them in FOREIGN KEY constraints, which are the first choice to enforce referential integrity. Related answer on dba.SE with detailed instructions:
Enforcing constraints “two tables away”
Another option would be to "fake" an IMMUTABLE function doing the check and use that in a CHECK constraint. Postgres will allow this, but be aware of possible caveats. Best make that a NOT VALID constraint. See:
Disable all constraints and table checks while restoring a dump
A CHECK constraint is not an option if you need joins. You can create a trigger which raises an error instead.
Have a look at this example: http://www.postgresql.org/docs/9.1/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE
CREATE TABLE emp (
empname text,
salary integer,
last_date timestamp,
last_user text
);
CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION 'empname cannot be null';
END IF;
IF NEW.salary IS NULL THEN
RAISE EXCEPTION '% cannot have null salary', NEW.empname;
END IF;
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := current_timestamp;
NEW.last_user := current_user;
RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;
CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
...i did it so (nazwa=user name, firma = company name) :
CREATE TABLE users
(
id bigserial CONSTRAINT firstkey PRIMARY KEY,
nazwa character varying(20),
firma character varying(50)
);
CREATE TABLE test
(
id bigserial CONSTRAINT firstkey PRIMARY KEY,
firma character varying(50),
towar character varying(20),
nazwisko character varying(20)
);
ALTER TABLE public.test ENABLE ROW LEVEL SECURITY;
CREATE OR REPLACE FUNCTION whoIAM3() RETURNS varchar(50) as $$
declare
result varchar(50);
BEGIN
select into result users.firma from users where users.nazwa = current_user;
return result;
END;
$$ LANGUAGE plpgsql;
CREATE POLICY user_policy ON public.test
USING (firma = whoIAM3());
CREATE FUNCTION test_trigger_function()
RETURNS trigger AS $$
BEGIN
NEW.firma:=whoIam3();
return NEW;
END
$$ LANGUAGE 'plpgsql'
CREATE TRIGGER test_trigger_insert BEFORE INSERT ON test FOR EACH ROW EXECUTE PROCEDURE test_trigger_function();
I have set of sql statements (create table, views, sequences), Where my schema name changes all the time and rest of the sql be the same.
Even in schema name a part of it has to change, for example:
I have a schema name ABC_XYZ, i would like to change this schema name to ABC_DEF_XYZ.
For this i tried to insert a variable in the schema name like ABC_&var1_XYZ. If i pass the variable in the schema name as shown here (ABC_&var1_XYZ) and pass the value to the variable, It ask me to declare the vaue of the variable.
I have given the error and the code i use below:
Error report -
ORA-06550: line 5, column 52:
PLS-00201: identifier 'REL4' must be declared
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
ORA-06550: line 7, column 51:
PLS-00201: identifier 'REL4' must be declared
here is my create statement:
set echo off
set verify off
undefine mySchemaPart
declare
vSQL varchar2(32767);
begin
vSQL:= 'begin EXECUTE IMMEDIATE alter table ABC_'||&&mySchemaPart||'_OWNER.TEST drop constraint EMPLOYEE_ID_FK; EXCEPTION when others then if (SQLCODE != -02443 and SQLCODE != -942) then RAISE; end if; end';
execute immediate vSQL;
vSQL:= 'begin EXECUTE IMMEDIATE drop table ABC_'||&mySchemaPart||'_OWNER.TEST cascade constraints PURGE; EXCEPTION when others then if SQLCODE != -942 then RAISE; end if; end';
execute immediate vSQL;
vSQL:= 'create table ABC_'||&mySchemaPart||'OWNER.TEST
(
EMPLOYEE_ID NUMBER(19) not null,
LAST_UPDT_DT DATE not null,
)';
execute immediate vSQL;
vSQL:= 'CREATE OR REPLACE SYNONYM ABC_USER.TEST FOR ABC_'||&mySchemaPart||'OWNER.TEST';
execute immediate vSQL;
vSQL:= 'begin EXECUTE IMMEDIATE alter table ABC_'||&mySchemaPart||'OWNER.TEST
add constraint EMPLOYEE_ID_FK foreign key (EMPLOYEE_ID)
references ABC_OWNER.GDSD (EMPLOYEE_ID); EXCEPTION when others then if (SQLCODE != -02443 and SQLCODE != -02275) then RAISE; end if; end';
execute immediate vSQL;
end;
/
Is there any other way i can try to insert my value in this schema.
You can use dynamic SQL to handle a varying schema in your DDL; for example:
accept mySchemaPart PROMPT "Schema part: "
declare
vMySchema varchar2(30) := 'ABC_' || '&mySchemaPart' || '_XYZ';
vSQL varchar2(32767);
begin
vSQL := 'create table ' || vMySchema || '.tableName (...)';
execute immediate vSQL;
end;
/
Pass it as 'ABC_||'&var1||'_XYZ'
An example of insert statement;
insert into test (a)
select 'ABC_'||&var1||'_XYZ' from dual ;
On execution it will ask for prompt.
As a block you can use this:
declare
var varchar2(100);
begin
var:='create table ABC_'||&var1||'_XYZ.tablnam(a number)'; --add your columns
dbms_output.put_line(var);
execute immediate var;
end;
As per #bin request his/her statments:
declare
var varchar2(500);
begin
var:='create table ABC_'||&var||'_OWNER.TEST(EMPLOYEE_ID NUMBER(19) not null, LAST_UPDT_DT DATE not null )';
--Table Created
dbms_output.put_line(var);
execute immediate var;
var:='alter table ABC_'||&var1||'_OWNER.TEST add constraint EMPLOYEE_ID_FK foreign key (EMPLOYEE_ID) references ABC_OWNER.GDSD(EMPLOYEE_ID)';
--Constraint Added
dbms_output.put_line(var);
execute immediate var;
var:='CREATE OR REPLACE SYNONYM ABC_USER.TEST FOR ABC_'||&var1||'_OWNER.TEST';
--Synonym Created
dbms_output.put_line(var);
execute immediate var;
var:='alter table ABC_'||&var1||'_OWNER.TEST drop constraint EMPLOYEE_ID_FK';
--Constraint Dropped
dbms_output.put_line(var);
execute immediate var;
var:='drop table ABC_'||&var1||'_OWNER.TEST cascade constraints PURGE';
--Table Dropped
dbms_output.put_line(var);
execute immediate var;
Exception
WHEN others then
dbms_output.put_line('Error--'||sqlerrm||'-'||sqlcode);
end;
Output:
SQL> declare
var varchar2(100);
begin
var:='create table ABC_'||&var1||'OWNER.TEST(EMPLOYEE_ID NUMBER(19) not null, LAST_UPDT_DT DATE not null )';
'
'
'
dbms_output.put_line(var);
execute immediate var;
end;
Enter value for var1: 'REL4'
create table ABC_REL4_OWNER.TEST(EMPLOYEE_ID NUMBER(19) not null, LAST_UPDT_DT DATE not null )
Table created.
alter table ABC_REL4_OWNER.TEST add constraint EMPLOYEE_ID_FK foreign key (EMPLOYEE_ID) references ABC_OWNER.GDSD(EMPLOYEE_ID)
Table altered.
CREATE OR REPLACE SYNONYM ABC_USER.TEST FOR ABC_REL4_OWNER.TEST
Synonym created.
alter table ABC_REL4_OWNER.TEST drop constraint EMPLOYEE_ID_FK
Table altered.
drop table ABC_REL4_OWNER.TEST cascade constraints PURGE
Table dropped.
How can place multiple "Begins" in a procedure to drop and create tables?
My attempt -
CREATE PROCEDURE procCreateCarTable
IS
BEGIN
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE CARS';
END;
COMMIT;
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE CARS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE VARCHAR2(10))';
COMMIT;
END;
END;
One by one the executes work but when creating this procedure I get the following error -
ORA-06550: line 5, column 1:
PLS-00103: Encountered the symbol "END"
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Here is the SQL procedure that I got to work as mentioned in my comment below -
CREATE PROCEDURE procCreateCarTable
IS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE CARS';
EXCEPTION WHEN OTHERS THEN NULL;
EXECUTE IMMEDIATE 'CREATE TABLE CARS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE
VARCHAR2(10))';
COMMIT;
END;
I added an EXCEPTION in case table CARS does not exist, but now my latest procedure below fails -
CREATE PROCEDURE procCreateCarTable
IS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE CARS';
EXCEPTION WHEN OTHERS THEN NULL;
EXECUTE IMMEDIATE 'CREATE TABLE CARS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE
VARCHAR2(10))';
EXECUTE IMMEDIATE 'DROP TABLE TRUCKS';
EXCEPTION WHEN OTHERS THEN NULL;
EXECUTE IMMEDIATE 'CREATE TABLE TRUCKS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE
VARCHAR2(10))';
COMMIT;
END;
The only reason I could think of as to why my latest procedure failed is because of the other 'EXCEPTION'. I do want the other one there so the procedure can still create the TRUCKS table. Any suggestions?
Through trial and error I created the procedure:
CREATE PROCEDURE procCreateCarTable
IS
BEGIN
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE CARS';
EXCEPTION WHEN OTHERS THEN NULL;
EXECUTE IMMEDIATE 'CREATE TABLE CARS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE
VARCHAR2(10))';
END;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE TRUCKS';
EXCEPTION WHEN OTHERS THEN NULL;
EXECUTE IMMEDIATE 'CREATE TABLE TRUCKS (ID VARCHAR2(1), NAME VARCHAR2(10), TITLE
VARCHAR2(10))';
END;
END;