PL/SQL:如何根据列值插入

Posted

技术标签:

【中文标题】PL/SQL:如何根据列值插入【英文标题】:PL/SQL: How to insert depending on column value 【发布时间】:2020-05-14 17:43:32 【问题描述】:

我是 PL/SQL 的新手。我尝试了各种方法来使用游标插入临时表,具体取决于临时表中是否已经存在该值。我要么得到太多行,要么没有插入任何内容。 这是我最后的伪代码方法,也是我试图完成的基本内容: 数据库:甲骨文 12 使用 SQL 开发人员 目标:从table1中获取重复的accountno信息并合并/合并到temptable中的单行 1. 如果 temptable 中不存在初始 accountno 信息,则添加 2. 如果 temptable 中存在 accountno,则将附加信息添加到 accountno 行

非常感谢您的建议。

伪代码

Declare
V_cnt number (20);
CURSOR c1 is select * from table1;
C1d c1%rowtype;
BEGIN
--
OPEN C1; 
        LOOP           
            FETCH C1 INTO c1d;
            EXIT WHEN C1%NOTFOUND;
--    Limit attempts
            IF LINE > 5 THEN EXIT; END IF;

 select accountno INTO v_cnt from table1 where Exists(select 1 from temptable where accountno <> c1d.accountno);                

           IF v_cnt is NULL THEN
            INSERT INTO temptable (accountno)
                values(c1d.accountno);
           END IF;

            LINE:= LINE + 1;

            END LOOP;

CLOSE C1;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
    dbms_output.put_line ('NO DATA');   
END;

【问题讨论】:

看看使用 MERGE 语句。 如果我理解你的最终目标,你不需要 pl/sql 也不需要游标。带有 MERGE 的简单 sql 应该可以做到。 docs.oracle.com/database/121/SQLRF/… 谢谢,我会阅读合并语法并试一试。 请用通俗易懂的语言描述您的需求,这个伪代码很难理解 获取 dup 帐号,它具有不同的联系信息集并将它们组合成临时表中的单个记录。如果临时表中不存在帐号,则创建记录。下次遇到 acc't no 时,将附加信息添加到临时表中,键入帐号。最初我使用 CURSOR 遍历表中的每一行并相应地更新临时表,即如果帐户号不存在则创建行,否则使用附加信息更新行,我无法使其工作。 Ed 的建议似乎满足了我的需要。如果我的解释不清楚,请告诉我 【参考方案1】:

如果你真的想更正你的伪代码,你可以试试 -

Declare
       V_cnt number (20);
       CURSOR c1 is  select * from table1;
       C1d c1%rowtype;
BEGIN
--
     OPEN C1; 
          LOOP           
              FETCH C1 INTO c1d;
              EXIT WHEN C1%NOTFOUND;
--    Limit attempts
              IF LINE > 5 THEN
                 EXIT;
              END IF;
              BEGIN
                   SELECT accountno
                     INTO V_cnt
                     FROM temptable
                    WHERE accountno = c1d.accountno
                      AND ROWNUM = 1;
              EXCEPTION
                       WHEN NO_DATA_FOUND THEN
                            V_cnt := NULL;
              END;

              IF V_cnt is NULL THEN
                 INSERT INTO temptable (accountno)
                                 values(c1d.accountno);
              END IF;

              LINE:= LINE + 1;

          END LOOP;
     CLOSE C1;
EXCEPTION
         WHEN NO_DATA_FOUND THEN
              dbms_output.put_line ('NO DATA');   
END;

我强烈建议使用下面的伪代码-

Declare
       V_cnt number (20);
       CURSOR c1 is  select * from table1;
       C1d c1%rowtype;
BEGIN
--
     OPEN C1; 
          LOOP           
              FETCH C1 INTO c1d;
              EXIT WHEN C1%NOTFOUND;
--    Limit attempts
              IF LINE > 5 THEN
                 EXIT;
              END IF;
              MERGE INTO temptable
              USING table1
              ON (accountno = c1d.accountno)
              WHEN NOT MATCHED THEN
                               INSERT (accountno)
                               values(c1d.accountno);
              LINE:= LINE + 1;

          END LOOP;
     CLOSE C1;
EXCEPTION
         WHEN NO_DATA_FOUND THEN
              dbms_output.put_line ('NO DATA');   
END;

【讨论】:

感谢您的建议。我可以使用该框架来优化我的查询以捕获任何丢失的行... vm

以上是关于PL/SQL:如何根据列值插入的主要内容,如果未能解决你的问题,请参考以下文章

动态修剪列值

PL/SQL 插入和分区

选择 PL/SQL 中两个非空列值之间的行集

如何使用 pl/sql 循环接受用户输入?

使用 PL SQL 将所有列值打印到仅记录

PL/SQL-如何使用游标的所有列插入表