【问题标题】:SQL - insert into table if value exists in another tableSQL - 如果值存在于另一个表中,则插入表中
【发布时间】:2011-12-02 12:12:32
【问题描述】:

我正在尝试使下面的 sql 查询正常工作,但出现错误,我的问题如下:

我需要遍历一个 select 语句的结果集(这部分很好)。在每一行的循环内,我需要检查 URL 是否存在于 tableA 中。如果是,则在 tableB 中插入一个映射,否则在 tableC 中插入一个新行。

这就是我所拥有的,但是当我尝试执行时,我在 IF 说 ORA-06550:第 8 行,第 15 列:PLS-00103:遇到符号“SELECT”时遇到了一个错误以下:( - + case mod new no.....

DECLARE 
STANDARD_LINK_ID TABLEB.LINK_ID%type;

BEGIN   
      FOR LINK_ROW IN ( SELECT LINKTEXT, LINKURL, CORPID FROM OLD_DATA)
      LOOP
          IF (SELECT COUNT(URL) FROM TABLEA WHERE URL = LINK_ROW.LINKURL) = 1
          THEN
            SELECT LINKID INTO STANDARD_LINK_ID FROM TABLEA WHERE URL = LINK_ROW.URL;
            INSERT INTO TABLEB(LINK_ID, CORP_ID) 
            VALUES (STANDARD_LINK_ID,  LINK_ROW.CORPID);
          ELSE
            INSERT INTO TABLEB(LINK_ID, LINK_NAME, URL, CORP_ID) 
            VALUES (SEQ_LINK.NEXTVAL, LINK_ROW.LINKTEXT, LINK_ROW.LINKURL, 
                                 LINK_ROW.CORP_ID);
          END IF;                 
      END LOOP;
    COMMIT;
END;

【问题讨论】:

    标签: sql oracle toad


    【解决方案1】:

    我怀疑你的 if 语句是罪魁祸首,因为你想要达到的目标绝对应该是可能的。请您尝试以下方法:

    DECLARE 
    STANDARD_LINK_ID TABLEB.LINK_ID%type;
    URL_COUNT NUMBER(10);
    
    BEGIN   
          FOR LINK_ROW IN ( SELECT LINKTEXT, LINKURL, CORPID FROM OLD_DATA)
          LOOP
              SELECT COUNT(URL) INTO URL_COUNT FROM TABLEA WHERE URL = LINK_ROW.LINKURL;
              IF URL_COUNT = 1 THEN
                SELECT LINKID INTO STANDARD_LINK_ID FROM TABLEA WHERE URL = LINK_ROW.URL;
                INSERT INTO TABLEB(LINK_ID, CORP_ID) 
                VALUES (STANDARD_LINK_ID,  LINK_ROW.CORPID);
              ELSE
                INSERT INTO TABLEB(LINK_ID, LINK_NAME, URL, CORP_ID) 
                VALUES (SEQ_LINK.NEXTVAL, LINK_ROW.LINKTEXT, LINK_ROW.LINKURL, 
                                     LINK_ROW.CORP_ID);
              END IF;                 
          END LOOP;
        COMMIT;
    END;
    

    希望它可以帮助您找出问题所在。

    【讨论】:

      【解决方案2】:

      我写得很快,但我认为这两个查询将解决您的问题而无需循环(这比一次插入要慢):

      -- insert to tableb when exists in tablea
      insert into tableb(link_id, corp_id) 
      select a.linkid, o.corpid
      from old_data o
      join tablea a on o.url = a.url
      
      
      -- insert to tablec when not exists in tablea
      insert into tablec(link_id, link_name, url, corp_id) 
      select seq_link.nextval, o.linktext, o.linkurl, o.corp_id
      from old_data o
      where not exists(select 1 from tablea a where o.url = a.url)
      

      ps。你不会忘记tablec 中的else 吗?

      【讨论】:

      • 现在我来自一个不同的世界,但如果在我的世界中设置操作比循环快得多。不知道oracle是否也是这样,请随时赐教
      • 我认为 SQL 世界中的 loop 是一种邪恶,尤其是当有办法使用一次点击中包含许多记录的结果集时(如本例所示)。
      • +1 我同意性能和避免循环通常是一件好事。
      • 在这种情况下,查询只是用于复制数据一次,所以谢天谢地,性能不是问题
      【解决方案3】:

      我见过这样做的;但不是在条件中嵌入返回值的选择

      https://forums.oracle.com/forums/thread.jspa?threadID=177035

      DECLARE 
      STANDARD_LINK_ID TABLEB.LINK_ID%type;
      DECLARE W_LINK_COUNT NUMBER (1,0);
      
      BEGIN   
            FOR LINK_ROW IN ( SELECT LINKTEXT, LINKURL, CORPID FROM OLD_DATA)
            LOOP
                SELECT COUNT(URL) INTO W_LINK_COUNT FROM TABLEA WHERE URL = LINK_ROW.LINKURL;
                IF  W_LINK_COUNT = 1
                THEN
                  SELECT LINKID INTO STANDARD_LINK_ID FROM TABLEA WHERE URL = LINK_ROW.URL;
                  INSERT INTO TABLEB(LINK_ID, CORP_ID) 
                  VALUES (STANDARD_LINK_ID,  LINK_ROW.CORPID);
                ELSE
                  INSERT INTO TABLEB(LINK_ID, LINK_NAME, URL, CORP_ID) 
                  VALUES (SEQ_LINK.NEXTVAL, LINK_ROW.LINKTEXT, LINK_ROW.LINKURL, 
                                       LINK_ROW.CORP_ID);
                END IF;                 
            END LOOP;
          COMMIT;
      END;
      

      【讨论】:

        猜你喜欢
        • 2012-09-17
        • 1970-01-01
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多