Dziękujemy za odpowiedzi Faceci. I Rodzaj rozwiązałem mój problem.

Próbowałem zaktualizować dane za pomocą REF kursora w Dynamic SQL za pomocą "gdzie prąd", ale teraz wiem, że nie działa.

Potem próbowałem użyć% Rowtype, aby przechowywać zarówno "ID", jak i "Clob" w jednej zmiennej, aby uzyskać przyszłe aktualizację, ale okazuje się słabe ref Cursor nie może użyć tego typu wiązania.

Po tym, jak próbowałem użyć rekordu jako powrotu kursora ref, który też nie działa na słabym kursorze.

Na końcu stworzyłem kolejny kursor, aby odzyskać "ID" oddzielnie wraz z kursorem, aby odzyskać "CLOB" w tym samym czasie, a następnie aktualizuj tabelę z tym identyfikatorem.


Obecnie pracuję nad zadaniem czyszczenia danych Oracle i ma wymaganie jak poniżej:

Istnieje 38 tabel (może więcej w przyszłości), a każda tabela ma jedną lub wiele kolumn, które typem jest CLOB. Muszę znaleźć różne słowo kluczowe w tych kolumnach i zgodnie z logiką zwracającej etykietę binarną kolumny i zapisz ją w nowej kolumnie.

Na przykład znajduje się tabela "Mytable1", która ma 2 kolumny CLOB "CLOB1" i "CLOB2". Chciałbym znaleźć słowo kluczowe "niebo" z tych kolumn i przechowywać "0" (jeśli nie znaleziono) lub "1" (jeśli znaleziono) w dwóch nowych kolumnach "Clob1sky", "Clob2sky".

Wiem, czy mógłbym napisać go w sposób statyczny, który zapewni wyższą wydajność, ale za każdym razem muszę go zmodyfikować dla tych bardzo podobnych zadań. Chcę zaoszczędzić trochę czasu, więc próbuję napisać go w sposób wielokrotnego użytku i nie wiązanie się z pewną tabelą.

Ale spotkałem problem podczas pisania programu. Mój program jest jak poniżej:

create or replace PACKAGE body LABELTARGETKEYWORD 
    as
    /**
    @param varcher tableName: the name of table I want to work on
    @param varchar colName: the name of clob column
    @param varchar targetWord: the word I want to find in the column
    @param varchar newColName: the name of new column which store label of clob 
    */ 
    PROCEDURE mainProc(tableName varchar, colName varchar,targetWord varchar,newColName varchar2)
    as
        type c_RecordCur is ref cursor;
        c_sRecordCur c_recordCur;
        /*other variables*/
    begin
        /*(1) check whether column of newColName exist
          (2) if not, alter add table of newColName
          (3) open cursor for retrieving clob
          (4) loop cursor
              (5) update set the value in newColName accroding to func labelword return
          (6) close cursor and commit*/
    end mainProc;

    function labelWord(sRecord VARCHAR2,targetWord varchar2) return boolean...
    function ifColExist(tableName varchar2,newColName varchar2) return boolean...
END LABELTARGETKEYWORD;

Większość DML i DDL są zapisywane w dynamicznym sposób SQL.

Problem polega na tym, kiedy piszę część (5), zauważę "gdzie prąd klauzuli nie może być używany w ref kursorze lub dynamicznej instrukcji SQL. Muszę więc zmienić plan.

Próbowałem użyć rekordu (ROWID, etykiety), aby przechowywać wynik i zmienić tabelę później. (Tabela jest używana tylko przez dwie osoby w mojej grupie, więc nie będzie problemu zmiany blokady i danych). Ale uważam, że staram się używać dynamicznego SQL, więc właściwie muszę zdefiniować kursor ref z powrotem pewnego% Rowtype i zasadniczo wszystkie inne zmienne,% typu instrukcji Dynamic SQL. Co sprawia, że czuję, że moja metoda ma coś złego.

Moje pytanie brzmi:

  1. Jeśli istnieje sposób na zdefiniowanie% typu dynamicznego SQL? Typ wiązania do zmiennej w Dynamic SQL?

  2. Czy ktoś mógłby dać mi wskazówkę, jak pisać (5) części w dynamicznym SQL?

  3. Czy nie powinienem projektować taki program?

  4. Czy nie jest tak, jak korzystać z dynamicznego SQL lub PLSQL?

Jestem bardzo nowy w pl / sql. Dziękuję Ci bardzo.

1
Jensen Fan 5 czerwiec 2018, 06:42

3 odpowiedzi

Najlepsza odpowiedź

Zgodnie z radą Toma Kyte, aby zrobić to w jednym oświadczeniu, jeśli można to zrobić w jednym oświadczeniu, spróbuję najpierw użyć jednego oświadczenia UPDATE:

CREATE TABLE mytable1 (id NUMBER, clob1 CLOB, 
  clob2 CLOB, clob1sky NUMBER, clob2sky NUMBER ) 
LOB(clob1, clob2) STORE AS SECUREFILE (ENABLE STORAGE IN ROW);

INSERT INTO mytable1(id, clob1, clob2) 
SELECT object_id, object_name, object_type FROM all_objects
 WHERE rownum <= 10000;

CREATE OR REPLACE 
PROCEDURE mainProc(tableName VARCHAR2, colName VARCHAR2, targetWord VARCHAR2, newColName VARCHAR2)
IS
  stmt VARCHAR2(30000);
BEGIN
  stmt := 'UPDATE '||tableName||' SET '||newColName||'=1 '||
          'WHERE DBMS_LOB.INSTR('||colName||','''||targetWord||''')>1';
  dbms_output.put_line(stmt);
  EXECUTE IMMEDIATE stmt;
END mainProc;
/

Więc dzwoniąc do mainProc('MYTABLE1', 'CLOB1', 'TAB', 'CLOB1SKY'); pożaruje oświadczenie

UPDATE MYTABLE1 SET CLOB1SKY=1 WHERE DBMS_LOB.INSTR(CLOB1,'TAB')>1

Który wydaje się robić sztuczka:

SELECT * FROM mytable1 WHERE clob1sky=1;

id  clob1    clob2  clob1sky clob2skiy
33  I_TAB1   INDEX  1   
88  NTAB$    TABLE  1   
89  I_NTAB1  INDEX  1   
90  I_NTAB2  INDEX  1   
...
1
wolφi 6 czerwiec 2018, 08:53

Nie jestem pewien ze swoim pytaniem Jeśli ta zadanie jest przypuszcza się codziennie lub co godzinę, bieżącym zapytaniem przez to będzie bardzo kosztowne. Jedną rzeczą, którą możesz zrobić - umieść wszystkie dane clob w pliku i zapisz go na serwerze (chyba musi być Linux). Następnie możesz utworzyć skrypt powłoki i zaplanować zadanie do uruchomienia gerp i pobrać wymaganą wartość i ", jeśli zostanie znalezione, a następnie zaktualizuj tabelę".

0
Atul Kr Dey 5 czerwiec 2018, 04:32

Myślę, że powinieneś zbliżać się do problemu inny sposób: 1. Znajdź wszystkie potrzebne kolumny:

CURSOR k_clobs
select  table_name, column_name from dba_tab_cols where data_type in ('CLOB','NCLOB');

Lub 2 kursor (możesz zbudować zapytanie, jeśli masz więcej niż 1 clob na stół:

 CURSOR k_clobs_table
             select  DISTINCT table_name from dba_tab_cols where data_type in ('CLOB','NCLOB');

CURSOR k_clobs_columns(table_namee varchar(255)) is
         select column_name from dba_tab_cols where data_type in ('CLOB','NCLOB') and table_name = table_namee; 

Teraz jesteś w 100%, że sprawdzasz kolumnę, jest CLOB, więc nie musisz się martwić o typ danych;)

Nie jestem pewien, co chcesz osiągnąć, ale mam nadzieję, że może ci pomóc.

0
hakobot 5 czerwiec 2018, 05:35