繁体   English   中英

插入Oracle SQL或更新(如果值已存在)?

[英]Insert into Oracle SQL or Update if value already exist?

我想要的是: If key exist in Oracle SQL Table → UPDATE, otherwise do a INSERT

昨天玩了一整天之后,我设法获得了INSERT部分(下面的查询),现在我需要的是UPDATE部分。

这就是为什么我需要它:我有一个RadGridView(使用Telerik和WPF)。 当用户单击“插入”按钮时,将添加一个新行,并且在用户单击Enter后,该值将插入到数据库中。 但是用户也可以单击RadGridView中的可用行并更新值,因此我也需要更新数据库中的值(而不是执行INSERT)。 这就是为什么我想要一个可以执行Udate或Insert的查询的原因。

感谢您的帮助,如果您有更好的实现INSERT部分的方法,我也想知道:)

我正在使用Oracle SQL Developer(Windows 10)。

PS。 我尝试了一些在StackOverflow上找到的解决方案,但无法将解决方案应用于我的问题。

表格1

+-----------------------------------+------------+--------+
|               ID                  |  ORIGTERM  |  CODE  |
+-----------------------------------+------------+--------+
| 126478                            | Grass      |  TEST  |
| 374628                            | Flower     |  TEST  |
| 128754                            | Tree       |  TEST  |
+-----------------------------------+------------+--------+

表2

+-----------------------------------+------------+---------+
|               ID                  |REPLACETERM |SYSCTLANG|
+-----------------------------------+------------+---------+
| 126478                            | Gras       |     3   |
| 374628                            | Blume      |     3   |
| 128754                            | Baum       |     3   |
+-----------------------------------+------------+---------+


我设法得到了INSERT查询,它看起来像这样(示例中插入了“ Plant”一词):

INSERT ALL 
   INTO Table1(origterm,code) VALUES (s_origterm,s_code) 
   INTO Table2(replaceterm) VALUES (s_replaceterm) 
  SELECT s_origterm, s_code, s_replaceterm 
    FROM (SELECT 'Plant' s_origterm, 'TEST' s_code, 'Pflanze' s_replaceterm FROM dual) 
    dual;

我还必须将Table2的ID更新为与Table1中的ID相同:

UPDATE Table2 SET Table2.ID = (SELECT Table1.ID FROM Table1 WHERE origterm='Plant') 
              WHERE replaceterm='Pflanze';

现在,我有一个看起来像这样的表:

    +-----------------------------------+------------+--------------+------+
    |               ID                  |  ORIGTERM  |  REPLACETERM | CODE |
    +-----------------------------------+------------+--------------+------+
    | 126478                            | Grass      |  Gras        | TEST |
    | 374628                            | Flower     |  Blume       | TEST |
    | 128754                            | Tree       |  Baum        | TEST |
    | 100000                            | Plant      |  Pflanze     | TEST |
    +-----------------------------------+------------+--------------+------+

SELECT g.ID, origterm, replaceterm, code FROM Table1 g, Table2 ct WHERE g.ID = ct.ID;

合并不适用于INSERT ALL。 如果要使用合并,则应在两个表中都使用而不是使用触发器来创建视图,而应针对该视图使用合并。 整个逻辑将在触发器内部。

编辑:合并不适用于此类视图ORA-38106:合并bei加入视图oder视图mit INSTEAD OF-Trigger nichtunterstützt

您可以创建两个合并语句(每个表一个)或一个插入语句,一个用于更新视图:

CREATE SEQUENCE MYDICT_SEQ START WITH 1 MAXVALUE 9999999999999999999999999999 MINVALUE 0;

CREATE VIEW mydict
AS
   SELECT a.id, a.origterm, a.code, b.replaceterm, b.sysctlang
     FROM table1 a LEFT OUTER JOIN table2 b ON a.id = b.id;   

CREATE OR REPLACE TRIGGER mydict_io
   INSTEAD OF INSERT OR UPDATE OR DELETE
   ON mydict
   FOR EACH ROW
DECLARE
   cnt1   INTEGER := 0;
   cnt2   INTEGER;
   nid    NUMBER;
BEGIN
   IF INSERTING OR UPDATING THEN
      IF :new.id IS NULL AND INSERTING THEN
         nid := mydict_seq.NEXTVAL;
      ELSE
         nid := :new.id;

         IF UPDATING THEN
            nid := :old.id;
         END IF;

         SELECT COUNT (*)
           INTO cnt1
           FROM table1
          WHERE id = nid;
      END IF;

      IF cnt1 = 0 THEN
         INSERT INTO TABLE1 (ID, ORIGTERM, CODE)
              VALUES (nID, :new.ORIGTERM, :new.CODE);
      ELSIF cnt1 > 0 THEN
         UPDATE TABLE1
            SET ORIGTERM = :NEW.ORIGTERM, CODE = :NEW.CODE
          WHERE id = nid;
      END IF;

      SELECT COUNT (*)
        INTO cnt2
        FROM table2
       WHERE id = nid AND SYSCTLANG = :new.SYSCTLANG;

      IF cnt2 = 0 THEN
         INSERT INTO TABLE2 (ID, REPLACETERM, SYSCTLANG)
              VALUES (nID, :new.REPLACETERM, :new.SYSCTLANG);
      ELSE
         UPDATE TABLE2
            SET REPLACETERM = :new.REPLACETERM
          WHERE id = nid AND SYSCTLANG = :new.SYSCTLANG;
      END IF;
   ELSIF DELETING THEN
      DELETE FROM table2
            WHERE id = :old.id AND SYSCTLANG = :old.SYSCTLANG;

      SELECT COUNT (*)
        INTO cnt2
        FROM table2
       WHERE id = nid;

      IF cnt2 = 0 THEN
         DELETE FROM table1
               WHERE id = :old.id;
      END IF;
   END IF;
END;

DECLARE
   nid   NUMBER;
BEGIN
   INSERT INTO mydict (ORIGTERM, CODE, REPLACETERM, SYSCTLANG)
        VALUES ('Plant', 'TEST', 'Pflanze', 3);
    nid := mydict_seq.currval;


   UPDATE mydict
      SET REPLACETERM = 'Fabrik'
    WHERE id = nid;

   UPDATE mydict
      SET REPLACETERM = 'Usine', SYSCTLANG = 4
    WHERE id = nid;
END;

用触发器代替触发器的逻辑可以做得更好,但我将其留给您;)

也许这太明显了,但是如果您拥有'key'值,那么此过程可能会起作用:

DECLARE _flag AS INT = 0;

SELECT COUNT() INTO _flag FROM table1 WHERE ID = key;

IF _flag = 0 THEN
   INSERT ...
ELSE
   UPDATE ....
END IF;

根据您自己的代码需求和/或ORACLE SQL方言进行调整。

一个可能的解决方案是使用MERGE关键字,在此处记录:

http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.htm

合并基本上是一个“ upsert”命令,这意味着它将更新行(如果存在)或插入(如果不存在)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM