How can drop table if table exists in oracle? - oracle11g

I am trying to create database by my java application using my generated schema file. In schema I have included drop query also. But I want to do some improvements for DROP QUERY. So I want to check the existence of db objects before running drop query and drop only when if it exists.
I googled for it and found some oracle link, Some link suggest following syntax and some mentioned that ORACLE does not support such syntax.
SYNTAX A:
IF EXISTS DROP TABLE TABLE_NAME
SYNTAX B:
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
I also tried following queries:-
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' )
DROP TABLE [BBB]
but it was giving error:-
Error starting at line 2 in command:
DROP TABLE [BBB]
Go
Error report:
SQL Error: ORA-00903: invalid table name
00903. 00000 - "invalid table name"
*Cause:
*Action:
Error starting at line 1 in command:
IF EXISTS (SELECT * FROM dba_objects WHERE OBJECT_NAME = 'BBB' ) DROP TABLE [BBB]
Error report:
Unknown Command
I refered following links:-
https://community.oracle.com/thread/2421779?tstart=0
Please suggest me if there any other queries to drop table with condition if table exists.

Drop table with no check. If any error exists you'll never know when something went wrong.
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
Or you can search in Oracle dictionary.
DECLARE
l_cnt NUMBER;
BEGIN
SELECT count(*)
INTO l_cnt
FROM user_tables
WHERE table_name = 'MY_TABLE';
IF l_cnt = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE my_table';
END IF;
END;

If you run following code you do not have to check if table exists and in case of errors (table is locked with now wait or any other you will know about it)
begin
for c1 in (select owner,table_name from dba_tables where table_name='MY_TABLE') loop
execute immediate 'drop table '||c1.owner||'.'||c1.table_name||'';
end loop;
end;

Try this : It will drop table 'table_name' if it is present .
declare
a varchar2(700) ;
begin
execute immediate ' SELECT CASE WHEN tab = 1
THEN ''DROP TABLE TABLE_NAME''
ELSE ''select 1 from dual''
END
FROM ( SELECT sum(case when table_name = ''TABLE_NAME'' then 1 else 0 end ) as tab FROM user_tables)' into a;
EXECUTE IMMEDIATE a;
end;

Related

Liquibase : Expected something between the "TABLE" keyword and the "IF" keyword

I am trying to run the below sql by liquibase and I am getting an error expected something between "TABLE" and the keyword "IF" keyword .This is for teradata database
CREATE MULTISET TABLE IF NOT EXISTS SCHEMA_NAME.TABLE_NAME, NO, FALLBACK,
NO BEFORE JOURNAL,
NO AFTER JOURNAL,
CHECKSUM = DEFAULT,
DEFAULT MERGEBLOCKRATIO AS ( I TRIED WITHOUT "AS")
(
COL1 INTEGER,
COL1 INTEGER....ETC)
PRIMARY INDEX( COL1,COL2);
REPLACE PROCEDURE <database_name>.drop_if_exists( in_object varchar(50)) begin IF EXISTS(
SELECT 1
FROM dbc.tables
WHERE tablename = in_object
and databasename='<database_name>') THEN
CALL DBC.SysExecSQL('DROP TABLE ' || in_object);
END IF; END;
Followed by the regular create table statment.

oracle plsql procedure dynamic count of the tables in cursor loop

I want to update all the tables having ABC column.Need to skip the tables which doesn't have data.I am having problem in checking the count of the table in a cursor loop.
PLSQL code
create or replace procedure testp is
CURSOR c_testp
IS
SELECT table_name,
column_name
FROM all_tab_columns
WHERE column_name IN('ABC')
ORDER BY table_name;
c int;
BEGIN
FOR table_rec IN c_testp
LOOP
BEGIN
SELECT COUNT(*)
INTO c
FROM table_rec.table_name;
IF(c>0) THEN
query := 'update '||table_rec.table_name||' set '||table_rec.column_name ||'= xyz';
EXECUTE IMMEDIATE query;
COMMIT;
END IF;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('data not found');
WHEN OTHERS THEN
dbms_output.put_line('others');
END;
END LOOP;
END;
In your code, use this:
EXECUTE IMMEDIATE 'SELECT count(*) FROM ' || table_rec.table_name INTO c;
instead of this:
SELECT COUNT(*)
INTO c
FROM table_rec.table_name;
However, as mentioned in comments - there is actually no need to perform that condition check, as no update will be performed when table is empty.

PL/SQL EXECUTE IMMEDIATE, table name not valid

I have to create a new table for each entry in a separate table(Studenti in my case) dynamically. I am just starting to learn about Dynamic Sql. I use the fallowing procedure:
CREATE or REPLACE PROCEDURE carnet_student IS
CREATE_TABLE_QUERY VARCHAR2(250);
CURSOR table_name is SELECT NR_MATRICOL FROM STUDENTI;
nume CHAR(4);
BEGIN
OPEN table_name;
LOOP
FETCH table_name INTO nume;
EXIT when table_name%NOTFOUND;
CREATE_TABLE_QUERY:='Create TABLE '||nume||'(
column1 varchar2(50),
column2 varchar2(50),
column3 number(2),
column4 DATE
)';
EXECUTE IMMEDIATE CREATE_TABLE_QUERY;
END LOOP;
CLOSE table_name;
END;
/
BEGIN
carnet_student;
END;
I receive the error ORA-00903: invalid table name. Any ideas how to solve this?

Delete all records from a schema in oracle pl sql

I am using oracle 10g.
I want to delete all the records from every table of a schema (user) with child records present.
I have tried to disable all the constraints present in every table and then try to delete the records.
But it took the whole day to do so.
Do we have a better way to do it?
I have tried this
BEGIN
FOR i IN (SELECT table_name FROM user_tables)
LOOP
EXECUTE IMMEDIATE 'delete from' || '"'||i.table_name||'"';
END LOOP;
COMMIT;
END;
but exceptions comes as child records are present.
I want something like this.
BEGIN
FOR i IN (SELECT table_name FROM user_cons_columns)
LOOP
for j in (select column_name from i.table_name)
loop
EXECUTE IMMEDIATE 'alter table "'||i.table_name||'"'||' disable constraint "'||j.column_name||'"';
end loop;
END LOOP;
COMMIT;
END;
Please help me out a little here.
You can use data pump, export your schema:
expdp system/s
directory=backup_dir
CONTENT=METADATA_ONLY
dumpfile=YOUR_SCHEMA_HEREmetaddl.dmp
schemas=YOUR_SCHEMA_HERE
logfile=YOUR_SCHEMA_HERE.$Date.log
then drop your schema:
drop user YOUR_SCHEMA_HERE cascade;
and then import it:
impdp system/s
directory=backup_dir
dumpfile=YOUR_SCHEMA_HEREmetaddl.dmp
logfile=imp_log_of_meta.log
Try executing the following and then delete all tables which are having child records.
You could change the query to enable constraints upon deletion of all records.
BEGIN
FOR c IN ( SELECT c.owner, c.table_name, c.constraint_name
FROM user_constraints c, user_tables t
WHERE c.table_name = t.table_name
AND c.status = 'ENABLED'
AND constraint_type = 'R'
ORDER BY c.constraint_type DESC)
LOOP
DBMS_UTILITY.exec_ddl_statement (
'alter table "'
|| c.owner
|| '"."'
|| c.table_name
|| '" disable constraint '
|| c.constraint_name);
END LOOP;
END;
/

ROWTYPE definition in pl/sql

I have written a PL/SQL Procedure which compares data between two tables and print the difference if any, but the twist is the table names to the procedure is dynamic. Here is the procedure
create or replace PROCEDURE compareTables(
tabA IN VARCHAR2, tabB IN VARCHAR2) AS
cur_tab_name USER_TABLES%ROWTYPE;
lv_sql varchar2(4000);
lv_sql2 varchar2(4000);
BEGIN
--SELECT TABLE_NAME INTO cur_tab_name FROM USER_TABLES WHERE TABLE_NAME = tabA;
lv_sql2 := 'SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME = :b_tabA';
EXECUTE IMMEDIATE lv_sql2 INTO cur_tab_name USING tabA;
<<child>>
DECLARE
TYPE cursor_ref IS REF CURSOR;
cur_comp_result cursor_ref;
rec_comp_result cur_tab_name.TABLE_NAME%rowtype;
BEGIN
lv_sql := 'SELECT * FROM '||tabA||' MINUS SELECT * FROM '||tabB;
OPEN cur_comp_result FOR lv_sql;
LOOP
FETCH cur_comp_result INTO rec_comp_result;
EXIT WHEN cur_comp_result%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(rec_comp_result.empid || '' || rec_comp_result.name);
END LOOP;
CLOSE cur_comp_result;
Exception
When others then
dbms_output.put_line('The Problem is '||sqlerrm);
END;
END compareTables;
Now the problem is when I compile this procedure I am getting the following error
Error at line 14: PLS-00310: with %ROWTYPE attribute, 'CUR_TAB_NAME.TABLE_NAME' must name a table, cursor or cursor-variable
line 14:rec_comp_result cur_tab_name.TABLE_NAME%rowtype;
how will I solve it?
*NB: I don't have oracle installed in my system. I am using Oracle Apex Online tool which uses
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 and
PL/SQL Release 11.2.0.3.0
As a test, go to the last line, and after the semicolon, hit enter.
I know that Pro*C in particular will gag without a line terminator at the end of the file.
You may be encounting that issue.
Outside the scope of your question consider
SELECT columns
FROM TABLE1
MINUS
SELECT columns
FROM TABLE2
and
SELECT columns
FROM TABLE2
MINUS
SELECT columns
FROM TABLE1
Use: cur_tab_name.table_name. The variable CUR_TAB_NAMEis of type USER_TABLE%ROWTYPE, thus it has several fields.

Resources