簡體   English   中英

SQL光標何時加載數據?

[英]When is the SQL cursor loads the data?

我有以下腳本通過讀取遠程源表來更新本地表。 腳本運行正常,沒有任何錯誤。 這篇文章是為了適當地闡明,游標如何工作。

我從遠程源表Source_Product讀取數據,並最初插入到臨時表VW_PRODUCT 之后,我插入或更新PRODUCT表。

我的問題是。

1) product_cursor何時加載數據? 是當我們嘗試在for循環中讀取游標時? 還是在聲明游標時加載數據?

2)該腳本每天運行。 如果product_cursor在聲明后VW_PRODUCT運行,則VW_PRODUCT具有前一天的數據。 因為仍然沒有將今天的數據插入到VW_PRODUCT表中(在游標聲明之后可以使用插入查詢)。 因此product_cursorminus之后將沒有任何記錄。 因為ysterday_data minus ysterday_data為零。 那么如何根據以下腳本將最新數據更新或插入PRODUCT

SET serveroutput ON SIZE 1000000;

DECLARE
   CURSOR product_cursor
   IS
        SELECT V.PRODUCTID,
               V.PACKAGEID'
               V.ENDDATE               
          FROM VW_PRODUCT V
        MINUS
        SELECT E.PRODUCTID,
               E.PACKAGEID,
               E.ENDDATE               
          FROM PRODUCT E;

   /*The delete data*/
   CURSOR product_cursor_del
   IS
        SELECT E.PRODUCTID FROM PRODUCT E WHERE (E.ENDDATE > SYSDATE OR E.ENDDATE IS NULL)
        MINUS
        SELECT V.PRODUCTID FROM VW_PRODUCT V;

   /* Variable Declaration*/
   v_total           NUMBER (10);
   v_inserted        NUMBER (10);
   v_updated         NUMBER (10);
   v_deleted         NUMBER (10);
   v_rows_inserted   NUMBER (10);
   v_productid       PRODUCT.PRODUCTID%TYPE;
   v_count           NUMBER (10);
   v_commit_point    NUMBER        := 25;
BEGIN
   v_total := 0;
   v_count := 0;
   v_inserted := 0;
   v_updated := 0;
   v_deleted := 0;
   v_rows_inserted := 0;

   EXECUTE IMMEDIATE 'TRUNCATE TABLE VW_PRODUCT';
   INSERT INTO VW_PRODUCT
      SELECT * FROM Source_Product;

   SELECT COUNT (*)
     INTO v_rows_inserted
     FROM VW_PRODUCT;

   COMMIT;

    /*delete data*/
   FOR product_rec IN product_cursor_del
   LOOP
      BEGIN
         v_total := v_total + 1;

         update product set enddate = sysdate
               WHERE productid = product_rec.productid and enddate is null;

         v_deleted := v_deleted + 1;
         v_count := v_count + 1;

         IF (v_count >= v_commit_point)
         THEN
            COMMIT;
            v_count := 0;
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            BEGIN
               DBMS_OUTPUT.put_line (   'Exception with product: ' );

            END;
      END;
   END LOOP;

   FOR product_rec IN product_cursor
   LOOP
      BEGIN
         v_total := v_total + 1;

        SELECT productid
            INTO v_productid
          FROM product
         WHERE productid = product_rec.productid;

        update PRODUCT
           set PACKAGEID        = product_rec.PACKAGEID,        
               ENDDATE          = product_rec.ENDDATE          
         WHERE PRODUCTID = product_rec.PRODUCTID;
         v_updated := v_updated + 1;
      EXCEPTION
         WHEN NO_DATA_FOUND
         THEN
           INSERT INTO PRODUCT
             (PRODUCTID,PACKAGEID,ENDDATE)
           VALUES
             (product_rec.PRODUCTID,
             product_rec.PACKAGEID,
             product_rec.ENDDATE);

            v_inserted := v_inserted + 1;
            v_count := v_count + 1;

            IF (v_count >= v_commit_point)
            THEN
               COMMIT;
               v_count := 0;
            END IF;
         WHEN OTHERS
         THEN
            raise_application_error ('Error );
      END;
   END LOOP;
  IF (v_total >= 1)
  THEN
    COMMIT;
  END IF;
END;
/

簡而言之,要回答您的基本問題,

  1. 游標不存儲任何結果集,它是用於從結果集中 獲取行指針
  2. 在聲明階段不消耗內存。
  3. 當您實際使用游標時,它是FETCH語句。 FETCH語句從結果集中檢索行,並將其放入內存中的某個區域。 您可以一次獲取一行,一次獲取幾行,也可以一次獲取全部。

FETCH語句執行以下操作:

  • 將結果集中當前行的數據讀取到輸出PL / SQL變量中。
  • 將指針移動到結果集中的下一行。

看一下使用游標

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM