如何排除更新所有表的循环表pgsql



我试图通过将id字段设置为主键来更新所有表。我有一个没有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大小写中,如何使表被跳过而不是返回通知?

你有几个问题。

  1. 声明前缺少DO(可能是打字错误)
  2. 在Select后缺少分号(;)。
  3. If语句是不必要的,因为查询已经消除了任何表
  4. IF语句后的End循环无效,此时有没有循环。
  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;
$$;

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

要只获取没有主键的表,请将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'
) ;

这将排除定义了主键的任何表,无论它定义在满足其他要求的哪些列上。

最新更新