Create script to drop several tables (PostgreSQL) - sql

I want to create a script that detect and drop the public tables in my posgresql database...
The request I build is the following :
SELECT CONCAT('DROP TABLE ', table_schema,'.',table_name,';') AS stmt FROM information_schema.TABLES
WHERE table_schema='public' AND table_catalog='capsana'
Here is a screenshot of the output I got
I want now to execute the commands (in the stmt column) in an automatic way .. without doing copy paste !
Is there any way to do that ?

You can use dynamic sql to do this;
DO $$
DECLARE
drop_stmt text;
BEGIN
FOR drop_stmt IN
SELECT CONCAT('DROP TABLE ', table_schema,'.',table_name) AS stmt
FROM information_schema.TABLES
WHERE table_schema='public' AND table_catalog='capsana' LOOP
EXECUTE drop_stmt;
END LOOP;
END$$;

Related

Can I select data across multiple schemas within the same SQL database?

I have one database with multiple schemas. I would like to run SELECT * FROM info, across all schemas that starts with "team".
The schemas are not fixed, meaning that schemas are added and dropped continuously, so I can't hardcode the schemas in the query. But I'm only interested in schemas that starts with "team". How do I do this?
If all tables have an identical structure, you can write a PL/pgSQL function that does this:
create function get_info(p_schema_prefix text)
returns table (... column definitions go here ...)
as
$$
declare
l_rec record;
l_sql text;
begin
for l_rec in select table_schema, table_name
from information_schema.tables
where table_name = 'info'
and table_schema like p_schema_prefix||'%'
loop
l_sql := format('select id, data from %I.%I', l_rec.table_schema, l_rec.table_name);
return query execute l_sql;
end loop;
end;
$$
language plpgsql;
The use it like this:
select *
from get_info('team')

How to delete all schemas in postgres

I'm using django-tenants, and for some tests I need to delete all schemas at once, so I was wondering how could I delete all schemas with a single sentence/script from postgresql shell, because deleting one by one is not scalable.
Thx so much.
For deleting all schemas you must use dynamic SQL. And schema names you can get from statistic system tables (example: information_schema). Example Query:
do
$body$
declare
f_rec record;
begin
for f_rec in
SELECT schema_name::text
FROM information_schema.schemata
where schema_name <> 'public'
loop
execute 'DROP SCHEMA ' || f_rec.schema_name || ' CASCADE';
end loop;
end;
$body$
language 'plpgsql';

SQL query help - find table in unknown schema and query data

I have a couple of simple queries I run manually in Oracle as sysdba to check the version info for a java application. The tricky part is that the schema names vary, so sometimes I have to search for the table to find the owner/schema and then query the info.
Is there a way to take the output from one query and use it to perform a schema-qualified query, so it can be automated?
The queries I use are:
SELECT username FROM dba_tables WHERE table_name LIKE 'APPVERSDATA%';
SELECT max(appfullversion) from SCHEMA.APPVERSDATA;
There must be a way to pass the name of the schema from the first query as a variable to the second query?
Edit: Ultimately I would like to set the output as a variable in shell script.
TIA
I assume that SCHEMA.APPVERSDATA would be the output of the first query so the best thing to do might be execute some PL/SQL as a store function or procedure:
DECLARE
l_schema varchar2(10);
BEGIN
SELECT DISTINCT owner
INTO l_schema
FROM dba_tables
WHERE table_name LIKE 'APPVERSDATA%';
EXECUTE IMMEDIATE 'SELECT max(appfullversion) from ' || l_schema || '.APPVERSDATA';
end;
/
This doesn't address what you are going to do with the data once it executes though. Update the question and I'll update the answer.
Edit(Version 2!):
So your shell would look something like this:
x () {
sqlplus -s u/p<<EOF
set serveroutput on;
set feedback off;
DECLARE
l_schema varchar2(10);
BEGIN
SELECT DISTINCT owner
INTO l_schema
FROM dba_tables
WHERE table_name LIKE 'APPVERSDATA%';
EXECUTE IMMEDIATE 'SELECT max(appfullversion) from ' || l_schema || '.APPVERSDATA';
dbms_output.put_line(l_return);
end;
/
EOF
}
echo $(x $1)

Oracle | drop table

I want to drop certain tables in a tablespace that has common name appended to end of each table for an example:
TABLE1_NAME1_COMMON
TABLE2_NAME2_COMMON
TABLE3_NAME3_COMMON
I heard about Oracle functions but I'm not familiar much with those so I'm expecting some helping hand.
Thanks.
If you're completely sure what you're doing, ie, if you're sure that you don't accidentally drop a table that you don't want to drop, you can do a:
set serveroutput on size 1000000
begin
for r in (
select table_name
from user_tables
where table_name like '%\_COMMON' escape '\')
loop
execute immediate 'drop table ' || r.table_name;
end loop;
exception when others then
dbms_output.put_line(sqlerrm);
end;
/
Edit:
Changed Now selecting from user_tables instead of dba_tables as it seems more safe to do.
Added set serveroutput on in order for dbms_output.put_line to be printed
Added begin .. exception .. end in order for errors to be shown.
You could do that in a procedure, but it might be better to just select those DROP-statements, review them and execute them manually:
SELECT 'DROP TABLE ' || table_name || ';'
FROM user_tables
WHERE table_name LIKE '%\_COMMON' ESCAPE '\';
would return
DROP TABLE TABLE1_NAME1_COMMON;
DROP TABLE TABLE2_NAME2_COMMON;
DROP TABLE TABLE3_NAME3_COMMON;
to identify them you can use:
SELECT * FROM user_tables WHERE tablespace_name='MySpace' AND table_name like '%COMMON';
You could then either, derive your DROP statements using a SELECT. Or you could write a PL/SQL function to loop through the "Common Tables" and DROP them using EXECUTE IMMEDIATE.
I would make sure you are 100% sure in the selections first however.

What am I doing wrong in this MySQL stored procedure?

I'm trying to use the following stored procedure.
DELIMITER $$
CREATE DEFINER=`root`#`localhost`
PROCEDURE `DeleteField`( IN _TABLENAME Text, IN _FIELDNAME text)
BEGIN
if exists (select * from information_schema.Columns
where table_name = _TABLENAME and column_name = _FIELDNAME)
then
alter table _TABLENAME drop column _FIELDNAME;
end if;
END
So I do Call('anytable','Anyfield') and I get the Error
Error Code:1146Table'Database._tablename'doesn't exist
This _tablename should be my parameter, not a string.
Plz some help before I hang myself, I love my life far too much.
I expect you will need to create a dynamic SQL query to do this.
An example of how to do this is at:
http://www.java2s.com/Code/SQL/Procedure-Function/Createadynamicstatementinaprocedure.htm
This would be the alter table replacement, though I have tested this.
DECLARE l_sql VARCHAR(4000);
SET l_sql=CONCAT_ws(' ',
'ALTER table ',_TABLENAME,' drop column ',_FIELDNAME);
SET #sql=l_sql;
PREPARE s1 FROM #sql;
EXECUTE s1;
DEALLOCATE PREPARE s1;