【问题标题】:update many to many records with postgresql / plpgsql使用 postgresql / plpgsql 更新多对多记录
【发布时间】:2012-06-12 08:36:18
【问题描述】:

我有一个基于 Web 的系统,该系统具有多个表(postgres/pgsql),这些表包含多对多关系,例如; 表 x column_id1 smallint FK column_id2 smallint FK

在这种情况下,更新基于 column_id2

首先要更新这些记录,我们将运行以下函数;

-- edited to protect the innocent
CREATE FUNCTION associate_id1_with_id2(integer[], integer) RETURNS integer
AS $_$
DECLARE
    a alias for $1;
    b alias for $2;
    i integer;
BEGIN
    delete from tablex where user_id = b;
    FOR i IN array_lower(a,1) .. array_upper(a,1) LOOP
        INSERT INTO tablex (
            column_id2,
            column_id1)
        VALUES (
            b,
            a[i]);
    end loop;
RETURN i;
END;
$_$ 
LANGUAGE plpgsql;

这看起来很草率,但现在添加了审核,它才真正显示出来。

我现在要做的只是删除和插入必要的行。

我一直在尝试以下各种形式,但没有运气

CREATE OR REPLACE FUNCTION associate_id1_with_id2(integer[], integer) RETURNS integer
AS $_$
DECLARE
    a alias for $1;
    b alias for $2;
c varchar;
    i integer;
BEGIN
    c = array_to_string($1,',');

    INSERT INTO tablex (
            column_id2,
            column_id1)
            (
    SELECT column_id2, column_id1
    FROM tablex
            WHERE column_id2 = b
    AND column_id1 NOT IN (c)
    );

    DELETE FROM tablex
    WHERE column_id2 = b
    AND column_id1 NOT IN (c);

RETURN i;
END;
$_$
LANGUAGE plpgsql;

根据我正在尝试的函数版本,当前版本存在各种错误,例如显式类型转换(我猜它不喜欢 c 是 varchar?)。

首先,我的方法是正确的还是有更优雅的解决方案,因为有几个表需要这种类型的处理?如果不能,请您指出正确的方向吗?

如果这是正确的方法,请您协助 where 子句的 NOT IN 部分的数组转换?

【问题讨论】:

    标签: postgresql plpgsql


    【解决方案1】:

    代替array_to_string,使用unnest将数组转换为一组行(就好像它是一个表一样),问题可以用vanilla SQL解决:

    INSERT INTO tablex(column_id1,column_id2)
     select ai,b from unnest(a) as ai where not exists
      (select 1 from tablex where column_id1=ai and column_id2=b);
    
    DELETE FROM tablex
    where column_id2=b and column_id1 not in
      (select ai from unnest(a) as ai);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 2022-01-23
      相关资源
      最近更新 更多