2017-05-22 41 views
0

我試圖來檢查表是否存在,如果沒有的話則必須創建一個,但我發現下面當我嘗試錯誤當它被認爲已經被創建時向其中插入數據。 這裏是我的腳本:無法創建不使用PL/SQL動態SQL存在的表

PROCEDURE CREAR_CLAVES 
AS 
    VERIFACION INTEGER; 
BEGIN 
    SELECT COUNT(TNAME) INTO VERIFACION FROM TAB WHERE TNAME = 'CLAVES'; 
    IF VERIFACION = 0 THEN 
    EXECUTE IMMEDIATE 'CREATE TABLE CLAVES (IDESTUDIANTE NUMBER(5) PRIMARY KEY, USUARIO VARCHAR2(1000), CONTRASENA VARCHAR2(1000))'; 
    EXECUTE IMMEDIATE 'ALTER TABLE CLAVES ADD CONSTRAINT FK_IDESTUDIANTE FOREIGN KEY (IDESTUDIANTE) REFERENCES ESTUDIANTES(ID)'; 
    ELSE 
    DBMS_OUTPUT.PUT_LINE('LA TABLA YA EXISTE'); 
    END IF; 
END CREAR_CLAVES; 


PROCEDURE IDENTIFICAR_ESTUDIANTES 
AS 
    VESTUDIANTES SYS_REFCURSOR; 
    ACTUAL ESTUDIANTES%ROWTYPE; 
    CONSULTA VARCHAR2(1000); 
BEGIN 
    CONSULTA := 'SELECT ID, NOMBRE, APELLIDO FROM ESTUDIANTES'; 
    OPEN VESTUDIANTES FOR CONSULTA; 
    FETCH VESTUDIANTES INTO ACTUAL; 
    WHILE VESTUDIANTES%FOUND 
    LOOP 
    INSERT 
    INTO CLAVES VALUES 
     (
     ACTUAL.ID, 
     LOWER(ACTUAL.APELLIDO) 
     ||LOWER(ACTUAL.NOMBRE), 
     LOWER(ACTUAL.NOMBRE) 
     ||DBMS_RANDOM.VALUE(100, 999) 
    ); 
    FETCH VESTUDIANTES INTO ACTUAL; 
    END LOOP; 
    CLOSE VESTUDIANTES; 
END IDENTIFICAR_ESTUDIANTES; 

我得到的表或視圖不存在錯誤。 任何想法如何解決它?

+0

嗨,這不是創造PL/SQL表中的好方法,** **重新思考在解決方案中,有一種更好的方法來完成這項工作沒有像這樣在運行時創建的表,也許我們可以幫助如果你向我們提供你想要做的事情 – hmmftg

+2

plus:如果表存在,並且它已經有你想要添加的約束:那麼是什麼? –

+0

這不是一個好方法。不過,實際的問題可能是,一旦表創建,以便通過CREAR_CLAVES每次運行將看到一個表需要即使一個以前創建創建你不插入一行到TAB。嘗試從「乾淨」環境中進行測試。 – BriteSponge

回答

1

最有可能的問題是,當程序被編譯恆山不存在。它甚至沒有達到檢查它的存在並創建它的程度。

您可以通過將「INSERT INTO恆山......」言成執行立即解決這個問題。使用綁定變量存在,以避免SQL注入的可能性:

CREATE or replace PROCEDURE IDENTIFICAR_ESTUDIANTES 
AS 
    VESTUDIANTES SYS_REFCURSOR; 
    ACTUAL ESTUDIANTES%ROWTYPE; 
    CONSULTA VARCHAR2(1000); 
BEGIN 
    CONSULTA := 'SELECT ID, NOMBRE, APELLIDO FROM ESTUDIANTES'; 
    OPEN VESTUDIANTES FOR CONSULTA; 
    FETCH VESTUDIANTES 
    INTO ACTUAL; 
    WHILE VESTUDIANTES%FOUND LOOP 
     execute immediate 'INSERT INTO CLAVES VALUES (:IDESTUDIANTE, :USUARIO, :CONTRASENA)' 
      using ACTUAL.ID, LOWER(ACTUAL.APELLIDO)||LOWER(ACTUAL.NOMBRE), LOWER(ACTUAL.NOMBRE)||DBMS_RANDOM.VALUE(100, 999); 

     FETCH VESTUDIANTES 
     INTO ACTUAL; 
    END LOOP; 
    CLOSE VESTUDIANTES; 
END IDENTIFICAR_ESTUDIANTES; 
/

順便說一句,我也disourage上即時的恆山的創建。此外,這將是更好地貫徹落實遊標循環和行由行(慢的慢)插入一個「插入爲選擇」 statment,除非你這裏變換有一個非常具體的,程序重邏輯將行列入CLAVES。

+0

謝謝你的回答,正如我所說,這是一堂課練習,我只是想知道它是否可能。 – JMz