【问题标题】:How to replace a string (data value) in whole database?如何替换整个数据库中的字符串(数据值)?
【发布时间】:2015-01-29 02:56:38
【问题描述】:

我想替换所有表中的子字符串,说我想在 postgres 中用“Centre”替换“Center”。那么有没有办法做到这一点?我发现了一个similar 问题来替换特定列中的子字符串。

仅供参考。 :我正在使用“pgAdmin III”。 我无法通过解决类似问题来解决我的问题。我不知道任何表和任何列名。所以我想替换整个数据库和所有列中的值。

【问题讨论】:

  • 正如您在链接到的问题中所回答的那样:update table set field = replace(field, 'cat', 'dog')。根据需要对每个表(和字段)执行此操作。对于大规模更改,您还可以转储数据,在 .sql 文件中查找/替换,然后重新导入。
  • 我尝试这样做但无法在整个数据库中替换。
  • 因为你做不到。您一次只能修改一个表,因此需要遍历所有表的列表,并使用每个表的所有适用列运行查询。或者,如果您确定要批发,转储数据,查找/替换,重新导入。
  • 我不知道所有具有该数据值的表和列名,因此使用给定的方法是不可能的。如果您能说明更多或从问题中删除重复的标志,将不胜感激。
  • @PuneetPurohit 你知道哪些表可以执行此任务吗?以及哪些列??

标签: database postgresql replace dynamic-sql


【解决方案1】:

使用此选择查询获取所有表及其列(数据类型为文本或字符的列,因为您要更新文本字段)

SELECT column_name,table_name 
FROM   information_schema.columns 
WHERE  table_schema='public' 
AND    (data_type ='text' OR data_type ='character varying') 
AND    table_name in (SELECT table_name 
                      FROM   information_schema.tables 
                      WHERE  table_schema='public' AND table_type ='BASE TABLE')

将其包装在动态 SQL 中以根据您的条件进行更新

DO
$$
DECLARE 
rw record;
BEGIN
FOR rw IN 
    SELECT 'UPDATE '||C.table_name||'  SET '||C.column_name||' = REPLACE ('||C.COLUMN_NAME||',''Center'',''Centre''); ' QRY
    FROM (SELECT column_name,table_name 
          FROM   information_schema.columns 
          WHERE  table_schema='public' 
          AND    (data_type ='text' OR data_type ='character varying')
          AND    table_name in (SELECT table_name 
                                FROM   information_schema.tables 
                                WHERE  table_schema='public' 
                                AND    table_type ='BASE TABLE'))c

LOOP
    EXECUTE rw.QRY;
END LOOP;
END;
$$;

【讨论】:

  • 错误:“用户”或附近的语法错误第 1 行:更新用户 SET firstname = REPLACE (firstname,'Center','Ce... ^ QUERY: UPDATE user SET firstname = REPLACE (firstname ,'Center','Centre'); CONTEXT: PL/pgSQL function inline_code_block line 17 at EXECUTE statement ********** Error ********** ERROR: syntax error at or near “用户” SQL 状态:42601 上下文:PL/pgSQL 函数 inline_code_block 第 17 行在 EXECUTE 语句
  • @PuneetPurohit 只需在 for 循环中运行 SELECT 并评论你得到的结果
  • 我正在从所有表中获取所有列
  • @PuneetPurohit 不是首先在FOR 中选择SELECT,顺便说一句,它在我的示例DB 中工作
  • 非常好的逻辑。稍加修改就可以很好地为我工作。
【解决方案2】:

对 Vivek 的代码稍作修改:

DO
$$
DECLARE 
rw record;
BEGIN
FOR rw IN 
    SELECT 'UPDATE "'||C.table_name||'"  SET "'||C.column_name||'" = REPLACE ("'||C.COLUMN_NAME||'",''Center'',''Centre''); ' QRY
    FROM (SELECT column_name,table_name 
          FROM   information_schema.columns 
          WHERE  table_schema='public' 
          AND    (data_type ='text' OR data_type ='character varying')
          AND    table_name in (SELECT table_name 
                                FROM   information_schema.tables 
                                WHERE  table_schema='public' 
                                AND    table_type ='BASE TABLE'))c

LOOP
    EXECUTE rw.QRY;
END LOOP;
END;
$$;

我添加了一些双引号以使其在表名包含下划线符号时仍然有效。 在 PG 9.5.11-0ubuntu0.16.04 上完美运行。

【讨论】:

    猜你喜欢
    • 2021-02-22
    • 2019-06-13
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 2018-06-21
    相关资源
    最近更新 更多