在 PostgreSQL 中为带前缀的表创建索引

Create indexes for tables with prefix in PostgreSQL

我正在尝试实现一种为 Postgre 中的多个表创建多个索引的方法sql。

现在,我写了这样的东西

do $$

declare temprow record;
declare idx_name character varying(200);

begin

for temprow in
    select table_name from information_schema.tables where table_schema = 'public' and table_name like 'prefix%' order by table_name
loop
    idx_name := 'index_name_prefix_' || temprow.table_name || '_idx';
    create index idx_name ON temprow.table_name (column1 asc, column2 desc);
end loop;

end$$;

看起来应该可以,但没有错误

ERROR:  schema "temprow" does not exist

我想我会安排这个 sql 每周一次,因为这是我完成任务的正确方法

你能帮我找出这个问题吗SQL或者建议一个更好的方法来为多个表创建索引?

如果你有 create index idx_name ON temprow.table_name,table 名字 必须 是真实的 table ,不是带有包含 table 名称的字符串的变量,也不是 dynamically/indirectly 引用 table 名称的任何其他间接方式。

  • 哪里有 temprow.table_name 语法需要 schema.table
  • 因此,您要告诉 PostgreSQL 在模式 temprow
  • 中的 table table_name 上创建索引

您要找的是动态SQL;那是将 SQL 写入字符串的代码,然后单独执行该字符串。

DO $do$

DECLARE 
  temprow  RECORD;
  sql_stmt CHARACTER VARYING(1024);
BEGIN

  FOR temprow IN
    SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name like 'prefix%' ORDER BY table_name
  LOOP
    sql_stmt := FORMAT(
                  'create index index_name_prefix_%s_idx ON %s (column1 asc, column2 desc);',
                  temprow.table_name,
                  temprow.table_name
                );

    EXECUTE(sql_stmt);

  END LOOP;

END $do$;

工作示例:


不过请小心使用此模式。

  • 它开始让你面临 SQL 注入攻击.

看看如果有人试图通过滥用引用的 table 名称来攻击您会发生什么...