【问题标题】:Postresql: for loop over every id in tablePostgresql:for循环遍历表中的每个ID
【发布时间】:2021-03-05 01:07:09
【问题描述】:

我有以下脚本:

do
$do$
begin
    FOR i IN 1..450 LOOP
        if (1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i)
        and 1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER') )
            then raise notice 'id % :  owner only', i;
        elsif(0< (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i) )
            then 
                if(not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'APPLICANT'))
                    then raise notice 'id % :  adding applicant role', i; insert into document_configuration_role values (i, 'APPLICANT');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EXPERT'))
                    then raise notice 'id % :  adding expert role', i; insert into document_configuration_role values (i, 'EXPERT');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER'))
                    then raise notice 'id % :  adding owner role', i; insert into document_configuration_role values (i, 'OWNER');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'ADMIN'))
                    then raise notice 'id % :  adding admin role', i; insert into document_configuration_role values (i, 'ADMIN');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'HEAD'))
                    then raise notice 'id % :  adding head role', i; insert into document_configuration_role values (i, 'HEAD');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EMPLOYEE'))
                    then raise notice 'id % :  adding employee role', i; insert into document_configuration_role values (i, 'EMPLOYEE');
                end if;
                if(  EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'RECOMMENDER'))
                    then raise notice 'id % :  removing recommender role', i; delete from document_configuration_role dc where dc.document_configuration_id = i and dc.role_name like 'RECOMMENDER';
                end if;
                if(  6 = (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i))
                    then raise notice 'id % :  all roles assigned', i; 
                end if;
        else
            raise notice 'id % :  not existing', i;
        end if;
    end loop;
end;
$do$

我在这里声明了一个硬编码的迭代器(从1到450),但我只想通过document_configuration_role.document_configuration_id进行迭代,如何实现?

我尝试了类似下面的声明我记录:

do
$do$
declare i record;
begin
    FOR i IN (select dcr2.document_configuration_id from document_configuration_role dcr2) LOOP
        if (1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i)
        and 1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER') )
            then raise notice 'id % :  owner only', i;
        elsif(0< (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i) )
            then 
                if(not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'APPLICANT'))
                    then raise notice 'id % :  adding applicant role', i; insert into document_configuration_role values (i, 'APPLICANT');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EXPERT'))
                    then raise notice 'id % :  adding expert role', i; insert into document_configuration_role values (i, 'EXPERT');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER'))
                    then raise notice 'id % :  adding owner role', i; insert into document_configuration_role values (i, 'OWNER');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'ADMIN'))
                    then raise notice 'id % :  adding admin role', i; insert into document_configuration_role values (i, 'ADMIN');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'HEAD'))
                    then raise notice 'id % :  adding head role', i; insert into document_configuration_role values (i, 'HEAD');
                end if;
                if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EMPLOYEE'))
                    then raise notice 'id % :  adding employee role', i; insert into document_configuration_role values (i, 'EMPLOYEE');
                end if;
                if(  EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'RECOMMENDER'))
                    then raise notice 'id % :  removing recommender role', i; delete from document_configuration_role dc where dc.document_configuration_id = i and dc.role_name like 'RECOMMENDER';
                end if;
                if(  6 = (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i))
                    then raise notice 'id % :  all roles assigned', i; 
                end if;
        else
            raise notice 'id % :  not existing', i;
        end if;
    end loop;
end;
$do$

但它显示错误:

SQL 错误 [42883]:错误:运算符不存在:bigint = 记录
提示:没有运算符匹配给定的名称和参数类型。你可能 需要添加显式类型转换。其中:PL/pgSQL 函数 IF 处的 inline_code_block 第 5 行

您对如何仅通过表中的 id 进行迭代有什么建议吗?

【问题讨论】:

  • 是否 select dcr2.document_configuration_id from document_configuration_role dcr2 返回缩放器值?有什么价值? select document_configuration_id 的数据类型是什么?
  • 您已将i 声明为record。为了获得document_configuration_id,您需要执行i.document_configuration_id。如果您只需要使用document_configuration_id,则将i 声明为整数。

标签: sql postgresql loops


【解决方案1】:

您只是将查询中的 configuration_id 提取到 i 中。

尝试将 i 声明为 bigint 而不是记录。

【讨论】:

    【解决方案2】:

    如果您想遍历 document_configuration_role 中的所有 document_configuration_id(分配给 i),则使用 document_configuration_id 的数据类型声明 i(我假设它为 bigint)。 p>

    do $$
    declare i bigint;
    
    begin
    FOR i IN
       select dcr2.document_configuration_id from document_configuration_role dcr2
    LOOP  
            if (1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i)
            and 1= (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER') )
                then raise notice 'id % :  owner only', i;
            elsif(0< (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i) )
                then 
                    if(not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'APPLICANT'))
                        then raise notice 'id % :  adding applicant role', i; insert into document_configuration_role values (i, 'APPLICANT');
                    end if;
                    if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EXPERT'))
                        then raise notice 'id % :  adding expert role', i; insert into document_configuration_role values (i, 'EXPERT');
                    end if;
                    if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'OWNER'))
                        then raise notice 'id % :  adding owner role', i; insert into document_configuration_role values (i, 'OWNER');
                    end if;
                    if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'ADMIN'))
                        then raise notice 'id % :  adding admin role', i; insert into document_configuration_role values (i, 'ADMIN');
                    end if;
                    if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'HEAD'))
                        then raise notice 'id % :  adding head role', i; insert into document_configuration_role values (i, 'HEAD');
                    end if;
                    if( not EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'EMPLOYEE'))
                        then raise notice 'id % :  adding employee role', i; insert into document_configuration_role values (i, 'EMPLOYEE');
                    end if;
                    if(  EXISTS (select (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i and  dcr.role_name like 'RECOMMENDER'))
                        then raise notice 'id % :  removing recommender role', i; delete from document_configuration_role dc where dc.document_configuration_id = i and dc.role_name like 'RECOMMENDER';
                    end if;
                    if(  6 = (select count (dcr.role_name) from document_configuration_role dcr where dcr.document_configuration_id = i))
                        then raise notice 'id % :  all roles assigned', i; 
                    end if;
            else
                raise notice 'id % :  not existing', i;
            end if;
        end loop;
    end;$$
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多