2017-02-07 51 views
0

對存儲過程的某些更改似乎不是呃...... Oracle承認。對存儲過程的某些更改似乎不起作用

例如,我爲我的過程添加了一個參數,重新編譯它(在DataGrip中講),並從我的代碼中調用它。它似乎工作,它接受了新的參數。

但是我犯了一個錯誤,給它的類型「INT」,它似乎不是一個有效的類型。我嘗試將其更改爲「NUMBER」,但行爲仍然相同。

讓我解釋一下。我在表中添加了一個主鍵(嘿,不要判斷我,我在事實之後走了進來,我從來不會創建沒有主鍵的表),並將它作爲參數添加到前一個程序員的存儲過程中無論是插入還是更新。然而,他們用作唯一約束的價值已經不再是唯一的了,所以我添加了主鍵。

但是,每次我運行該過程,而不是添加一個新行,因爲一個字段具有相同的值,它會更新現有的行。就好像永遠不會識別ID參數那樣,這是一個新的行。請參閱下面的代碼以進行說明。

幸運的是,一位同事之前遇到過這個問題,並告訴我,如果我要複製過程定義,重命名並提交它,然後運行它,它就會起作用。所以我做了。它確實如此。

那麼,有沒有人知道爲什麼一些存儲過程的變化得到甲骨文的認可,而一些變化卻沒有?如果這與緩存或Oracle存儲這些過程的方式有關?是否有一個命令可以運行來「刷新」程序的存儲,因爲它似乎不會自動執行?

謝謝大家!

這裏有三個版本的程序:原始的,我的第一次變化得到承認,我的第二次變化沒有得到承認。注意v_ID參數

原文:

create PROCEDURE  proc_name_removed_for_privacy 
    ( v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR 
    ) 
    as 

v_IsNew CHAR(1):= 'T'; 

BEGIN 
    SELECT DECODE(COUNT(Month_Year),0,'T','F') INTO v_IsNew 
     FROM table_name_removed_for_privacy 
    WHERE Month_Year = v_Month_Year; 

     IF UPPER(TRIM(v_IsNew)) = 'T' THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
      SET Title = v_Title, 
       modified_by = v_UserID, 
       date_modified = SYSDATE, 
       visible = v_Visible 
     WHERE Month_Year = v_Month_Year; 
     COMMIT; 

    END IF; 

END; -- Procedure 

二:

create PROCEDURE  proc_name_removed_for_privacy 
(
    v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR, 
    v_ID IN INT DEFAULT -1 
) as 

BEGIN 
    IF v_ID = -1 THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
     SET Title = v_Title, 
      modified_by = v_UserID, 
      date_modified = SYSDATE, 
      visible = v_Visible 
     WHERE ID = v_ID; 
     COMMIT; 
    END IF; 
END; -- Procedure 

三:

create PROCEDURE  proc_name_removed_for_privacy 
(
    v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR, 
    v_ID IN NUMBER DEFAULT -1 
) as 

BEGIN 
    IF v_ID = -1 THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
     SET Title = v_Title, 
      modified_by = v_UserID, 
      date_modified = SYSDATE, 
      visible = v_Visible 
     WHERE ID = v_ID; 
     COMMIT; 
    END IF; 
END; -- Procedure 
+0

其實我剛剛意識到,根據我所描述的行爲,我猜想我所做的任何更改都沒有被Oracle識別,這就是爲什麼它仍然基於現有的v_Month_Year進行更新值在原始過程中看到。 WTF。 – MystikDan

+0

'INT'只是'NUMBER'的子類型。 [oracle doc](https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/datatypes.htm) –

+0

*複製過程定義,重命名它並提交它*要添加參數,請使用ALTER程序。這應該強制重新編譯。順便說一句,我相信DDL語句通常會自動提交,所以它不應該做任何事情。 – Leigh

回答

0

嘗試:

create or replace procedure ... 

我的猜想是你沒有捕獲創建過程中的錯誤,所以你認爲你正在用更新的定義「更新」過程,但它真的只是出錯。通過使用「創建或替換」,您告訴Oracle創建新的其他程序是否使用新代碼更新現有過程。

我不知道這是肯定的(我沒有運行腳本),但是當我看到「創建過程」而不是「創建或替換」時,它會產生一個標誌。

希望有幫助!

+0

這並沒有提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 - [來自評論](/ review/low-quality-posts/15135847) – Robert

+0

@Robert如果我是對的,它應該解決問題。當我有更多的時間時,我會嘗試解釋更多,謝謝 – tbone

+0

@tbone它做到了,但它每次都不工作。所以幸運的是我的程序現在正在工作,但我仍然不能成功地更新或替換Oracle中的程序。 – MystikDan