动态 sql - 使用循环更新多行

Posted

技术标签:

【中文标题】动态 sql - 使用循环更新多行【英文标题】:Dynamic sql - update multiple rows with loop 【发布时间】:2020-04-30 11:55:48 【问题描述】:

我们有很多表,其中包含 3 个列 (RID,PARTNER,SUPPLIER)。我想更新这些列,但只在 4 个表中 - 取决于 PK。

所以我开始了一些事情,但我卡住了:

BEGIN
 FOR i IN
  (select table_name from all_tab_columns where column_name = 'RID' /*PK*/ 
   and column_name = 'PARTNER' or column_name = 'SUPPLIER')
 LOOP
  EXECUTE IMMEDIATE 'UPDATE  ' || i.table_name|| 'set PARTNER = :newvalue where PARTNER = :oldavalue and RID = :ridvalue'
  USING (newvalue, oldvalue, ridvalue)
END LOOP 
END

问题:

    我不知道,如何使用此方法更新多个列 (因为在表中存在PartnerSupplier,例如:在一个表中是Partner,在另一个表中是Supplier) 我只想更新(PartnerSupplier),但只能在 1 个表中更新,取决于 PK 这是一个可行的解决方案吗?

【问题讨论】:

【参考方案1】:

您需要在FOR 循环中使用条件USING 子句和稍微不同的查询,如下所示:

BEGIN
    FOR I IN (
        SELECT TABLE_NAME
               , PARTNER_COUNT
               , SUPPLIER_COUNT
        FROM (
            SELECT TABLE_NAME
                   , SUM(CASE WHEN COLUMN_NAME = 'RID' THEN 1 ELSE 0 END) AS RID_COUNT
                   , SUM(CASE WHEN COLUMN_NAME = 'PARTNER' THEN 1 ELSE 0 END) AS PARTNER_COUNT
                   , SUM(CASE WHEN COLUMN_NAME = 'SUPPLIER' THEN 1  ELSE 0 END) AS SUPPLIER_COUNT
            FROM ALL_TAB_COLUMNS
            WHERE COLUMN_NAME = 'RID'
                  OR COLUMN_NAME = 'PARTNER'
                  OR COLUMN_NAME = 'SUPPLIER'
        ) WHERE RID_COUNT = 1 AND PARTNER_COUNT + SUPPLIER_COUNT = 1
    ) LOOP
        EXECUTE IMMEDIATE 'UPDATE  '
                          || I.TABLE_NAME
                          || 'set :col_name = :newvalue where :col_name = :oldavalue and RID = :ridvalue'
            USING ( DECODE(PARTNER_COUNT,1,'PARTNER','SUPPLIER'),
                    NEWVALUE, 
                    DECODE(PARTNER_COUNT,1,'PARTNER','SUPPLIER'),
                    OLDVALUE, 
                    RIDVALUE );
    END LOOP;
END;
/

【讨论】:

正是我想要的。太棒了。

以上是关于动态 sql - 使用循环更新多行的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PL/SQL - 循环值作为没有动态 SQL 的动态列名

如何使用 Graphql 动态更新一个表中的多行

如何使用 CURSOR 更新 SQL 中的多行?

sql-内连接更新多行

用于更新多行的 PDO 循环

如何使用 linq to sql 一次更新多行?