截断 Postgres 数据库中的所有表
在重建之前,我经常需要删除 PostgreSQL 数据库中的所有数据。我如何直接在 SQL 中执行此操作?
目前,我已经设法想出一个 SQL 语句,它返回我需要执行的所有命令:
SELECT 'TRUNCATE TABLE ' || tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';
但是一旦我拥有它们,我就看不到以编程方式执行它们的方法。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
FrusteratedWithFormsDesigner 是正确的,PL/pgSQL 可以做到这一点。这是脚本:
这将创建一个存储函数(您只需执行一次),之后您可以像这样使用它:
FrustratedWithFormsDesigner is correct, PL/pgSQL can do this. Here's the script:
This creates a stored function (you need to do this just once) which you can afterwards use like this:
PL/pgSQL 中很少需要显式游标。使用 隐式游标 ="noreferrer">
FOR
循环:由于每个数据库的表名称不是唯一的,因此您必须对表名称进行架构限定以确保确定。另外,我将该函数限制为默认模式“public”。适应您的需求,但请务必排除系统架构
pg_*
和information_schema
。使用这些函数时要非常小心。他们会破坏你的数据库。我添加了儿童安全装置。注释
RAISE NOTICE
行并取消注释EXECUTE
以启动炸弹...format()
需要 Postgres 9.1 或更高版本。在旧版本中,像这样连接查询字符串:单个命令,无循环
因为我们可以 < strong>
TRUNCATE
一次多个表,我们根本不需要任何游标或循环:聚合所有表名并执行单个语句。更简单、更快:
调用:
精炼查询
您甚至不需要函数。在 Postgres 9.0+ 中,您可以在
DO< 中执行动态命令/code>
声明。在 Postgres 9.5+ 中,语法可以更简单:
关于
pg_class
、pg_tables
和information_schema.tables
之间的区别:关于
regclass
和引用的表名称:用于重复使用
使用您的普通结构和所有内容创建一个“模板”数据库(让我们将其命名为
my_template
)空桌子。然后执行DROP
/CREATE DATABASE
周期:这是非常快,因为 Postgres 在文件级别复制整个结构。没有并发问题或其他开销会减慢您的速度。
如果并发连接阻止您删除数据库,请考虑:
Explicit cursors are rarely needed in PL/pgSQL. Use the simpler and faster implicit cursor of a
FOR
loop:Since table names are not unique per database, you have to schema-qualify table names to be sure. Also, I limit the function to the default schema 'public'. Adapt to your needs, but be sure to exclude the system schemas
pg_*
andinformation_schema
.Be very careful with these functions. They nuke your database. I added a child safety device. Comment the
RAISE NOTICE
line and uncommentEXECUTE
to prime the bomb ...format()
requires Postgres 9.1 or later. In older versions concatenate the query string like this:Single command, no loop
Since we can
TRUNCATE
multiple tables at once we don't need any cursor or loop at all:Aggregate all table names and execute a single statement. Simpler, faster:
Call:
Refined query
You don't even need a function. In Postgres 9.0+ you can execute dynamic commands in a
DO
statement. And in Postgres 9.5+ the syntax can be even simpler:About the difference between
pg_class
,pg_tables
andinformation_schema.tables
:About
regclass
and quoted table names:For repeated use
Create a "template" database (let's name it
my_template
) with your vanilla structure and all empty tables. Then go through aDROP
/CREATE DATABASE
cycle:This is extremely fast, because Postgres copies the whole structure on the file level. No concurrency issues or other overhead slowing you down.
If concurrent connections keep you from dropping the DB, consider:
如果我必须这样做,我将简单地创建当前数据库的模式sql,然后删除&创建数据库,然后使用模式sql加载数据库。
以下是涉及的步骤:
1) 创建数据库的架构转储 (
--schema-only
)pg_dump mydb -s > schema.sql
2) 删除数据库
drop database mydb;
3) 创建数据库
create database mydb;
4) 导入架构
psql mydb
psql mydb
架构.sql
If I have to do this, I will simply create a schema sql of current db, then drop & create db, then load db with schema sql.
Below are the steps involved:
1) Create Schema dump of database (
--schema-only
)pg_dump mydb -s > schema.sql
2) Drop database
drop database mydb;
3) Create Database
create database mydb;
4) Import Schema
psql mydb < schema.sql
只需执行以下查询:
Just execute the query bellow:
在这种情况下,最好只使用一个空数据库作为模板,当您需要刷新时,删除现有数据库并从模板创建一个新数据库。
In this case it would probably be better to just have an empty database that you use as a template and when you need to refresh, drop the existing database and create a new one from the template.
简单地说,你可以运行这段 SQL :
Simply, you can run this piece of SQL :
我在这里没有看到的一件事是截断然后重置序列。请注意,像此处给出的所有内容一样的简单截断只会截断表,但会将序列保留为截断前的值。要在截断时将序列重置为其起始值,请执行以下操作:
您只需将 RESTART IDENTITY 添加到您喜欢的任何答案中,无需在此处重复。 CASCADE 可以解决您可能面临的任何外键约束。
One thing that I don't see here is truncating and then resetting sequences. Note that a simple truncate like all that have been given here will just truncate the tables, but will leave sequences at their pre-truncate values. To reset the sequences to their start values when you truncate do:
you can just add that RESTART IDENTITY to any of the answers you fancy, no need to repeat that here. CASCADE is there for any foreign key constraints you may face.
伙计们,更好、更干净的方法是:
1)创建数据库的架构转储(--schema-only)
pg_dump mydb -s > schema.sql
2) 删除数据库
删除数据库mydb;
3)创建数据库
创建数据库mydb;
4) 导入架构
psql mydb <; schema.sql
这对我有用!
祝你今天过得愉快。
海勒姆·沃克
Guys the better and clean way is to :
1) Create Schema dump of database (--schema-only)
pg_dump mydb -s > schema.sql
2) Drop database
drop database mydb;
3) Create Database
create database mydb;
4) Import Schema
psql mydb < schema.sql
It´s work for me!
Have a nice day.
Hiram Walker
清理
AUTO_INCRMENT
版本:Cleaning
AUTO_INCREMENT
version:你能用动态SQL依次执行每条语句吗?您可能必须编写 PL/pgSQL 脚本来执行此操作。
http://www.postgresql.org/docs/8.3/static/ plpgsql-statements.html(第 38.5.4 节。执行动态命令)
Could you use dynamic SQL to execute each statement in turn? You would probably have to write a PL/pgSQL script to do this.
http://www.postgresql.org/docs/8.3/static/plpgsql-statements.html (section 38.5.4. Executing Dynamic Commands)
您也可以使用 bash 执行此操作:
您将需要调整架构名称、密码和用户名以匹配您的架构。
You can do this with bash also:
You will need to adjust schema names, passwords and usernames to match your schemas.
要删除数据并保留 pgAdmin 中的数据并保留表结构,您可以执行以下操作:
For removing the data and preserving the table-structures in pgAdmin you can do:
如果您可以使用 psql 您可以使用
\gexec< /code> 执行查询输出的元命令;
注意
\gexec
是在 9.6 版本中引入的If you can use psql you can use
\gexec
meta command to execute query output;Note that
\gexec
is introduced into the version 9.6您可以使用类似的方法来获取所有截断查询。
You can use something like this to get all truncate queries.