Wrote this script:
static void schema()
{
Sql.newInstance(*DB_CONFIG, DB_DRIVER).execute('''
drop table if exists post;
drop table if exists author;
create table author(
id integer primary key,
name varchar(500)
);
create table post(
id integer primary key,
title varchar(500),
text longvarchar,
author integer not nul,
foreign key(author) references author(id)
);
''')
}
and after start, I see this:
"WARNING: Failed to execute:
because: ORA-00933: SQL command not properly ended"
I'm using Oracle 11g 2 database and oracle jdbc driver.
drop table if exists post;
drop table if exists author;
It is not a valid Oracle syntax. You could do it in the following way -
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE post';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE author';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
There is another syntax error -
author integer not nul,
Correct it to NOT NULL.
Related
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
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
so the problem is I have two tables and before inserting or updating the values on one table I have to check if the other table does not contain the new value I'm trying to insert/update like so:
CREATE TABLE categoriasimples(
nome varchar(64) PRIMARY KEY REFERENCES categoria(nome) ON DELETE CASCADE);
CREATE TABLE supercategoria(
nome varchar(64) PRIMARY KEY REFERENCES categoria(nome) ON DELETE CASCADE);
CREATE FUNCTION check_categoria_type_sup() RETURNS trigger AS $check_categoria_type_sup$
BEGIN
IF nome FROM categoriasimples WHERE (NEW.nome = CategoriaSimples.nome) IS NOT NULL THEN
RAISE EXCEPTION 'Uma categoria nao pode ser super e simples ao mesmo tempo!';
END IF;
RETURN NEW;
END;
$check_categoria_type_sup$ LANGUAGE plpgsql;
CREATE TRIGGER check_categoria_type_sup BEFORE INSERT OR UPDATE ON supercategoria FOR EACH ROW EXECUTE PROCEDURE check_categoria_type_sup();
CREATE FUNCTION check_categoria_type_simp() RETURNS trigger AS $check_categoria_type_simp$
BEGIN
IF nome FROM supercategoria WHERE (supercategoria.nome = NEW.nome) IS NOT NULL THEN
RAISE EXCEPTION 'Uma categoria nao pode ser simples e super ao mesmo tempo!';
END IF;
RETURN NEW;
END;
$check_categoria_type_simp$ LANGUAGE plpgsql;
CREATE TRIGGER check_categoria_type_simp BEFORE INSERT OR UPDATE ON categoriasimples FOR EACH ROW EXECUTE PROCEDURE check_categoria_type_simp();
I can insert values into one table but if I try to insert in the other table it says:
ERROR: invalid input syntax for type boolean: "bife" (Value that was in the other table)
CONTEXT: PL/pgSQL function check_categoria_type_sup() line 3 at IF
SQL state: 22P02
This is too long for a comment.
I'm pretty sure you can do what you want without using triggers. I would suggest that you investigate inheritance, which Postgres supports for tables.
You can just define a unique constraint on the parent table and not have to worry about trying to get two different tables to be in sync.
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;