Solución:
Para hacer esto en uno comando que necesita SQL dinámico con EXECUTE
en un DO
declaración (o función):
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$;
Esto incluye tablas de todos esquemas a los que el usuario actual tiene acceso. Excluí los esquemas del sistema por seguridad.
Si no escapa los identificadores correctamente, el código falla para cualquier identificador no estándar que requiera comillas dobles.
Además, corre el riesgo de permitir inyección SQL. Toda la entrada del usuario debe desinfectarse en código dinámico, que incluye identificadores potencialmente proporcionados por los usuarios.
¡Potencialmente peligroso! Todas esas tablas se abandonaron para siempre. Construí una seguridad. Inspeccione las declaraciones generadas antes de ejecutar realmente: comentario RAISE
y descomentar el EXECUTE
.
Si cualquier otro objeto (como vistas, etc.) depende de una tabla, obtendrá un mensaje de error informativo en su lugar, que cancela toda la transacción. Si está seguro de que todos los dependientes también pueden morir, agregue CASCADE
:
'DROP TABLE ' || _tbl || ' CASCADE;
Estrechamente relacionada:
- Actualizar columna en varias tablas
- Cambiar todos los ceros (si los hay) en todas las columnas (en una tabla) a … digamos 1
Alternativamente podrías construir sobre la mesa del catálogo pg_class
, que también proporciona la oid
de la mesa y es más rápido:
...
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
...
¿Catálogo del sistema o esquema de información?
- Cómo comprobar si existe una tabla en un esquema determinado
Cómo c.oid::regclass
defenderse de la inyección de SQL?
- Nombre de la tabla como parámetro de función de PostgreSQL
O hazlo todo en un soltero DROP
mando. Debería ser un poco más eficiente:
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$;
Relacionado:
- ¿Existe un comando de postgres para listar / eliminar todas las vistas materializadas?
Utilizando el catálogo de sistemas convenientemente adaptado pg_tables
en el último ejemplo. Y format()
por conveniencia. Ver:
- Cómo comprobar si existe una tabla en un esquema determinado
- Nombre de la tabla como parámetro de función de PostgreSQL
Suponga que el prefijo es ‘ventas_’
Paso 1: Obtenga todos los nombres de las tablas con ese prefijo
SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'sales_%';
Paso 2: Haga clic en el botón “Descargar como CSV”.
Paso 3: Abra el archivo en un editor y reemplace “Ventas_ con ,Ventas
y “ con un espacio
Paso 4: DROP TABLE sales_regist, sales_name, sales_info, sales_somthing;
Este es el comando del servidor sql, puedes probar este, si funcionó en postgres o no. Esta consulta generará el script sql para eliminar
SELECT 'DROP TABLE "' || TABLE_NAME || '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
[EDIT]
begin
for arow in
SELECT 'DROP TABLE "' || TABLE_NAME || '"' as col1
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
LOOP
--RAISE NOTICE '%',
EXECUTE 'DROP TABLE ' || arow ;
END LOOP;
end;