如何在更新所有 tables pgsql 的循环中排除 table

How do I exclude a table in loop that updates all tables pgsql

我试图通过将 id 字段设置为主键来更新所有 table。我有一个 table 没有 id 列,需要跳过它。这是我目前所拥有的,但似乎无法查询 运行:

DECLARE
    rec record;
BEGIN
    FOR rec IN 
        SELECT table_schema, table_name, column_name
        FROM information_schema.columns 
        WHERE column_name = 'id'
                if not FOUND then
                     raise notice'no id found' 
                end if; END LOOP

    LOOP
        EXECUTE format('ALTER TABLE %I.%I ADD PRIMARY KEY (id)',
            rec.table_schema, rec.table_name, rec.column_name);
    END LOOP;
END;
$$

我不断收到此错误:

ERROR:  missing "LOOP" at end of SQL expression
LINE 12:     end if; END LOOP; 

END LOOP 应该去哪里,如果不是紧跟在 if 案例之后?这个事件是他大规模更新主键的正确方法吗?此外,在 if 情况下,我如何才能跳过 table 而不是返回通知?

你有一些问题。

  1. 声明前缺少 DO(可能是打字错误)
  2. 您在 Select 之后缺少分号 (;)。
  3. If 语句不必要,因为查询已消除任何 table 会让它成为现实。
  4. IF语句后的End Loop无效,此时有 没有循环。
  5. 格式化立即执行将失败。它仅包含 2 参数 (%I),但您要传递 3 个值。你需要添加第三个 列的参数或不传递列名。

综合考虑:

do $$
    rec record;
begin
    for rec in 
        select table_schema, table_name 
          from information_schema.columns 
         where column_name = 'id'; 
    loop
        execute format('alter table %i.%i add primary key (id)',
            rec.table_schema, rec.table_name);
    end loop;
end;
$$;

您还有一个大问题需要解决。如果 table 已经有一个主键 ,id 或任何其他列甚至多个列,会发生什么情况。

要仅获取没有主键的 table,请将您的 select 更改为:

select col.table_schema, col.table_name 
          from information_schema.columns  col 
         where col.column_name = 'id' 
           and not exists ( select null
                              from information_schema.table_constraints   con 
                             where col.table_schema    = con.table_schema 
                               and col.table_name      = con.table_name 
                               and con.constraint_type = 'PRIMARY KEY'
                          ) ;

这不包括任何 table 定义了主键的列,无论它定义在满足其他要求的列上。