Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

drop all tables sharing the same prefix in postgres

I would like to delete all tables sharing the same prefix ('supenh_agk') from the same database, using one sql command/query.

like image 696
Roy Avatar asked Dec 22 '14 21:12

Roy


People also ask

How do you Drop multiple tables with common prefix in one query?

Here is my solution: SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;') FROM INFORMATION_SCHEMA. TABLES WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%'; And of course you need to replace TABLE_PREFIX_GOES_HERE with your prefix.

How do I delete multiple tables in PostgreSQL?

We can delete multiple rows in PostgreSQL by using the delete statement. We can delete the rows by using the where clause. The below example shows that delete multiple rows by using where condition in PostgreSQL. Explanation: In the above example, we have to delete four rows by using where clause.

How do you use the prefix to Drop a table?

SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) AS statement FROM information_schema. tables WHERE table_name LIKE 'myprefix_%'; This will generate a DROP statement which you can than copy and execute to drop the tables.

Can you Drop multiple tables in the same statement?

We can drop multiple tables together using a single DROP Table statement as well.


2 Answers

To do this in one command you need dynamic SQL with EXECUTE in a DO statement (or function):

DO
$do$
DECLARE
   _tbl text;
BEGIN
FOR _tbl  IN
    SELECT quote_ident(table_schema) || '.'
        || quote_ident(table_name)      -- escape identifier and schema-qualify!
    FROM   information_schema.tables
    WHERE  table_name LIKE 'prefix' || '%'  -- your table name prefix
    AND    table_schema NOT LIKE 'pg\_%'    -- exclude system schemas
LOOP
   RAISE NOTICE '%',
-- EXECUTE
  'DROP TABLE ' || _tbl;  -- see below
END LOOP;
END
$do$;

This includes tables from all schemas the current user has access to. I excluded system schemas for safety.

If you do not escape identifiers properly the code fails for any non-standard identifier that requires double-quoting.
Plus, you run the risk of allowing SQL injection. All user input must be sanitized in dynamic code - that includes identifiers potentially provided by users.

Potentially hazardous! All those tables are dropped for good. I built in a safety. Inspect the generated statements before you actually execute: comment RAISE and uncomment the EXECUTE.

If any other objects (like views etc.) depend on a table you get an informative error message instead, which cancels the whole transaction. If you are confident that all dependents can die, too, append CASCADE:

  'DROP TABLE ' || _tbl || ' CASCADE;

Closely related:

  • Update column in multiple tables
  • Changing all zeros (if any) across all columns (in a table) to... say 1

Alternatively you could build on the catalog table pg_class, which also provides the oid of the table and is faster:

...
FOR _tbl  IN
    SELECT c.oid::regclass::text  -- escape identifier and schema-qualify!
    FROM   pg_catalog.pg_class c
    JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
    WHERE  n.nspname NOT LIKE 'pg\_%'     -- exclude system schemas
    AND    c.relname LIKE 'prefix' || '%' -- your table name prefix
    AND    c.relkind = 'r'                -- only tables
...

System catalog or information schema?

  • How to check if a table exists in a given schema

How does c.oid::regclass defend against SQL injection?

  • Table name as a PostgreSQL function parameter

Or do it all in a single DROP command. Should be a bit more efficient:

DO
$do$
BEGIN
   RAISE NOTICE '%', (
-- EXECUTE (
   SELECT 'DROP TABLE ' || string_agg(format('%I.%I', schemaname, tablename), ', ')
   --  || ' CASCADE' -- optional
   FROM   pg_catalog.pg_tables t
   WHERE  schemaname NOT LIKE 'pg\_%'     -- exclude system schemas
   AND    tablename LIKE 'prefix' || '%'  -- your table name prefix
   );
END
$do$;

Related:

  • Is there a postgres command to list/drop all materialized views?

Using the conveniently fitting system catalog pg_tables in the last example. And format() for convenience. See:

  • How to check if a table exists in a given schema
  • Table name as a PostgreSQL function parameter
like image 55
Erwin Brandstetter Avatar answered Oct 15 '22 15:10

Erwin Brandstetter


Suppose the prefix is 'sales_'

Step 1: Get all the table names with that prefix

SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'sales_%';

Step 2: Click the "Download as CSV" button.

Step 3: Open the file in an editor and replace "sales_ with ,sales and " with a space

Step 4: DROP TABLE sales_regist, sales_name, sales_info, sales_somthing;

like image 35
Ryan Augustine Avatar answered Oct 15 '22 15:10

Ryan Augustine