Когда курсор SQL загружает данные?

У меня есть следующий скрипт для обновления локальной таблицы, читая таблицу удаленного источника. Скрипт работает без ошибок. Этот пост должен уточнить, как работает курсор.

Я читаю данные из таблицы удаленного источника Source_Product и изначально вставьте во временную таблицу VW_PRODUCT, После этого я вставляю или обновляю PRODUCT Таблица.

Мои вопросы

1) Когда product_cursor загрузить данные? Это когда мы пытаемся прочитать курсор в цикле for? или когда когда-нибудь объявить курсор он загружает данные?

2) Этот скрипт запускается ежедневно. Если product_cursor работает, как только он объявит, то VW_PRODUCT имеет данные за предыдущий день. Потому что данные за сегодня не вставлены в VW_PRODUCT таблица (запрос вставки доступен после объявления курсора). Итак product_cursor не будет иметь никакой записи после minus, Так как ysterday_dataminus 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 ответ

В двух словах, чтобы ответить на ваши основные вопросы,

  1. Курсор не хранит какой-либо набор результатов, это указатель, используемый для извлечения строк из набора результатов.
  2. Память не используется на этапе объявления.
  3. Это оператор FETCH, когда вы фактически используете курсор. Оператор FETCH извлекает строки из результирующего набора и помещает их в область в памяти. Вы можете выбрать строки по одному, несколько за раз или все сразу.

Оператор FETCH выполняет следующие операции:

  • Считывает данные для текущей строки в наборе результатов в выходные переменные PL/SQL.
  • Перемещает указатель на следующую строку в наборе результатов.

Посмотрите на работу с курсорами.

Другие вопросы по тегам