I put together a script that drops triggers, tables, indexes, and sequences.
BEGIN
/*Delete All Triggers */
FOR i in (select trigger_name,owner
from dba_triggers ) LOOP
EXECUTE IMMEDIATE 'DROP TRIGGER '||i.owner||'.'||i.trigger_name;
END LOOP;
/*Delete All Indexes*/
FOR ind IN
(SELECT index_name FROM user_indexes WHERE table_name = 'my_table' AND index_name NOT IN
(SELECT unique index_name FROM user_constraints WHERE
table_name = 'my_table' AND index_name IS NOT NULL))
LOOP
execute immediate 'DROP INDEX '||ind.index_name;
END LOOP;
/*Delete All Tables*/
FOR c IN (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE ('DROP TABLE ' || c.table_name || ' CASCADE CONSTRAINTS');
END LOOP;
/*Delete all Sequences*/
FOR s IN (SELECT sequence_name FROM user_sequences) LOOP
EXECUTE IMMEDIATE ('DROP SEQUENCE ' || s.sequence_name);
END LOOP;
END;
I was wondering if there is specific order I should do it? Is there anything else I need to consider?
Related
I have several schemas in my database. Most of the schemas have a table called orders. How do I iterate through the schemas that have that table and get a count of the number of records in each of those schemas for that table?
select * from information_schema.schemata;
see https://www.postgresql.org/docs/11/infoschema-schemata.html
do
$$
declare
tableName varchar := 'xyz';
schemaName varchar;
query text;
counter integer;
begin
for schemaName in select table_schema from information_schema.tables where table_name = tableName
loop
query := 'select count(*) from ' || schemaName || '.' || tableName;
execute query into counter;
raise notice E'% %', schemaName, counter;
end loop ;
end $$
I have an oracle database and I am running the below query
select table_name
from db_test.test
where table_name like '%20170128'
This returns me a column with all the tables with the specific date at the end.
How can I take this list and query them?
You'd need dynamic SQL. If you're running a simple query against each table (I'm just doing a count(*) in this example), something like this would work
declare
l_cnt integer;
l_sql varchar2(1000);
begin
for t in (select table_name
from db_test.test
where table_name like '%20170128')
loop
l_sql := 'select count(*) from ' || t.table_name;
execute immediate l_sql
into l_cnt;
dbms_output.put_line( t.table_name || ' has ' || l_cnt || ' rows.' );
end loop;
end;
When I execute the following code I get , sql command not ended properly.
I'm using this to find matching column for a string.
DECLARE
match_count INTEGER;
BEGIN
FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM '||t.table_name||' WHERE lower('||t.column_name||') like :1'
INTO match_count
USING 'XRWJ01';
IF match_count > 0 THEN
dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
END IF;
END LOOP;
END;
/
Debug your code... if you get an error print the statement erroring out. I made some minor changes to your pl/sql block. Replace v_owner and v_datatype with your values to run it.
set serveroutput on size 999999
clear screen
DECLARE
match_count INTEGER;
v_owner VARCHAR2(30);
v_data_type VARCHAR2(30);
v_stmt VARCHAR2(1024);
BEGIN
v_owner := 'SCOTT';
v_data_type := 'NUMBER';
FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and data_type = v_data_type) LOOP
v_stmt := 'SELECT COUNT(*) FROM "'||t.table_name||'" WHERE "'||t.column_name||'" like :1';
BEGIN
EXECUTE IMMEDIATE
v_stmt
INTO match_count
USING 'XRWJ01';
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line( 'Error in statement: '|| v_stmt );
dbms_output.put_line ( DBMS_UTILITY.FORMAT_ERROR_STACK() );
dbms_output.put_line ( DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() );
END;
IF match_count > 0 THEN
dbms_output.put_line( t.table_name ||' '||t.column_name||' '||match_count );
END IF;
END LOOP;
END;
/
I ran the statement locally and it errored out because of LOWER('||t.column_name||'). You select the columns from a data dictionary - those are the column names. If you do a LOWER then you might have different values if the tables/columns are created with case. Solution is to not do LOWER and put double quotes around them.
This was what i was trying
SET SERVEROUTPUT ON;
DECLARE
sql_query VARCHAR2(32767);
BEGIN
FOR t IN (SELECT table_name, column_name FROM user_tab_columns)
LOOP
EXECUTE IMMEDIATE sql_query := 'SELECT * FROM ' || t.table_name ;
END LOOP;
END;
This query gives you the number of distinct values per column (assuming that statistics are up to date).
select owner, table_name, column_name, num_distinct
from all_tab_col_statistics
Maybe this would be enough.
If you need to have the distinct values, you have to modify the sql_query param in your script as follows:
EXECUTE IMMEDIATE sql_query := 'SELECT distinct '|| t.column_name ||
' FROM ' || t.table_name ;
I had created a lot of tables and users while testing some SQL command and now I dont remember exactly all the tables and user's name.
But now I want to delete all of it for my big project.So is it possible to delete it in SQL command line ?
This PL/SQL block will be useful to delete all the data in oracle data base
BEGIN
FOR cur_rec IN (SELECT object_name, object_type
FROM user_objects
WHERE object_type IN
('TABLE',
'VIEW',
'PACKAGE',
'PROCEDURE',
'FUNCTION',
'SEQUENCE',
'SYNONYM',
'PACKAGE BODY'
))
LOOP
BEGIN
IF cur_rec.object_type = 'TABLE'
THEN
EXECUTE IMMEDIATE 'DROP '
|| cur_rec.object_type
|| ' "'
|| cur_rec.object_name
|| '" CASCADE CONSTRAINTS';
ELSE
EXECUTE IMMEDIATE 'DROP '
|| cur_rec.object_type
|| ' "'
|| cur_rec.object_name
|| '"';
END IF;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ( 'FAILED: DROP '
|| cur_rec.object_type
|| ' "'
|| cur_rec.object_name
|| '"'
);
END;
END LOOP;
END;
/
execute this command:
BEGIN
FOR table_ IN (SELECT * FROM dba_tables where owner like 'YOUR_SCHEMA') LOOP
execute immediate 'truncate table ' || table_.owner || '.' || table_.table_name ||' cascade';
END LOOP;
END;
/
BEGIN
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' DISABLE ALL CONSTRAINTS';
--This will disable all the constraint
END LOOP;
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||T.table_name;
END LOOP;
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' ENABLE ALL CONSTRAINTS';
END LOOP;
END;
Alter table ... disable all constraints throws a ORA-01735: invalid ALTER TABLE option if there is no constraint defined for the table, which would cause the script to fail to truncate every table if there is at least one table without constraint. You might want to place the execute immediate within a begin -exception block
You have two ways:
you can use function delete instead truncate for this function you should not disable constraints, but it work more slowly because you can rollback this operation if you will go this way:
BEGIN
FOR table_ IN (SELECT * FROM dba_tables where owner like 'YOUR_SCHEMA') LOOP
execute immediate 'delete from table ' || table_.owner || '.' || table_.table_name;
END LOOP;
END;
use truncate it is more faster, but you must diable constraints on table:
begin
for disable_constraint_ in
(select * from dba_constraints where owner= 'YOUR_SCHEMA'
)
loop
execute immediate 'alter table ' || disable_constraint_.owner || '.' || disable_constraint_.table_name ||' disable constraint '|| disable_constraint_.constraint_name;
end loop;
for table_ in (select * from dba_tables where owner = 'YOUR_SCHEMA')
loop
execute immediate 'truncate table ' || table_.owner || '.' ||table_.table_name ||' cascade';
end loop;
for enable_constaint_ in (select * from dba_constraints where owner= 'YOUR_SCHEMA')
loop
execute immediate 'alter table ' || enable_constaint_.owner || '.' || enable_constaint_.table_name ||' enable constraint '|| enable_constaint_.constraint_name;
end loop;
end;