【问题标题】:inserting record while looping inside cursor在游标内循环时插入记录
【发布时间】:2016-09-16 14:39:28
【问题描述】:

我是初学者,我有这个问题。所以我有一张桌子:

config_items:

id | item_key            | item_alias |   
---|---------------------|------------|  
5  | folder1.Move.hasFile| hasFile    |
4  | folder1.Move        | Move       |    
3  | folder2.Move        | Move       |
2  | folder3.Move        | Move       |  
1  | folder4.Download    | Download   |

我想获取item_key 中有.Move 的记录。获得这些记录后,我想在每个记录上添加 .hasFile 并将它们作为新记录插入到表中。但是,如果该 config_key 已经存在(例如 folder1.Move.hasFile),则不应将其添加到表中。我已经完成了以下操作,但它给了我 id 的主键违规错误。有人可以解释我在哪里做错了吗?

CREATE OR REPLACE PROCEDURE insert_hasFile(v_key IN config_items.item_key%TYPE)
AS 
BEGIN
    insert into config_items
            (id,
            item_key,
            item_alias)
            (select 
                (select max(id) from config_items)+1,
                 v_key,
                'hasFile'
            from 
                config_items
            where
                not exists(select * from config_items where v_key =item_key )
            );
END; 
/

DECLARE
CURSOR item_records_curr
IS
SELECT * from config_items
where item_key LIKE '%.Move';

v_item_key config_items.item_key%TYPE;
v_all_info item_records_curr%ROWTYPE;

BEGIN
   OPEN item_records_curr;

   LOOP 
      FETCH item_records_curr into v_all_info;     
       v_item_key := v_all_info.item_key || '.hasFile';
       insert_hasFile(v_item_key);
      EXIT WHEN item_records_curr%NOTFOUND;
   END LOOP;

   CLOSE item_records_curr;
END;

【问题讨论】:

  • PK 包含哪些列?只有身份证还是别的什么?
  • 使用max(id) 计算主键的唯一值是个坏主意。您应该使用序列 - 这是更好的方法。
  • @Aleksej id 是 PK。 item_key 必须是唯一的。
  • 你的insert-select每次调用可以插入多条记录,但最大值只有一个值,所以会尝试插入n条相同id的记录
  • @Aleksej 即使我使用 rownum 也会一样吗? select max(id) from config_items)+rownum

标签: sql database oracle plsql cursor


【解决方案1】:

假设您至少有 Oracle 12c,您可以在表声明中将 ID 设为身份字段,例如 ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY

这样您就不必担心尝试在 SP 中计算它,并且可以让系统为此生成密钥。

如此处所述。 http://docs.oracle.com/database/121/DRDAA/migr_tools_feat.htm#DRDAA109

【讨论】:

    【解决方案2】:

    在您的过程 insert_hasFile 中,您正在从 config_items 表中获取记录,该表将为 ID 列选择具有相同值的多条记录。

    尝试通过使用 DUAL 的过程插入单个记录,如下所示..

    `CREATE OR REPLACE PROCEDURE insert_hasFile(v_key IN config_items.item_key%TYPE)
    AS 
    BEGIN
        insert into config_items
                (id,
                 item_key,
                 item_alias)
                 (select 
                     (select max(id) from config_items)+1,
                      v_key,
                     'hasFile'
                 from 
                     dual
                 where
                     not exists(select * from config_items where v_key =item_key )
                ) ;
    END;  
    /`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多