2014-01-24 69 views
1

這已被多次詢問在網絡上殺甲骨文的會議,但沒有我在谷歌找到的答案可以解決我的問題。存儲過程由用戶名

我想創建一個殺死Oracle會話的存儲過程。該過程接受的唯一參數是要殺死的會話的擁有者的用戶名。

這是我的嘗試:

CREATE OR REPLACE PROCEDURE kill_user_session (
    username IN NVARCHAR2 
) 
AS 
    stmt varchar(5000); 
    CURSOR get_sessions 
     IS 
     SELECT s.sid sid, s.serial# ser 
      FROM v$session s, v$process p 
     WHERE s.username = username 
     AND p.addr(+) = s.paddr; 
    session_rec get_sessions%ROWTYPE; 
BEGIN 
    FOR session_rec in get_sessions LOOP 
     BEGIN 
      stmt := 'ALTER SYSTEM KILL SESSION ''' || session_rec.sid || ',' || session_rec.ser || ''''; 
      EXECUTE IMMEDIATE stmt; 
     --EXCEPTION WHEN others THEN 
     -- dbms_output.put_line('Error killing session: ' || stmt); 
     -- dbms_output.put_line(SQLERRM); 
     END; 
    END LOOP; 
END; 
/

如果我執行它像這樣

 exec kill_user_session('myuser'); 

我得到一個錯誤:

ERROR at line 1: 
ORA-00911: invalid character 
ORA-06512: at "SYSTEM.KILL_USER_SESSION", line 17 
ORA-06512: at line 1 

如果我改變線17

  stmt := 'ALTER SYSTEM KILL SESSION "' || session_rec.sid || ',' || session_rec.ser || '"'; 

然後我得到

ERROR at line 1: 
ORA-00026: missing or invalid session ID 
ORA-06512: at "SYSTEM.KILL_USER_SESSION", line 17 
ORA-06512: at line 1 

我已授予下列權利SYSTEM:

GRANT SELECT ON v$session TO SYSTEM; 
GRANT ALTER SYSTEM TO SYSTEM; 

但是這並沒有幫助。

編輯:我添加了一個dbms_output.putline打印出stmt變量,然後執行它。這裏有一個例子:

ALTER SYSTEM KILL SESSION "34,91" 

如果我在存儲過程之外執行這個語句,它運行良好,會話被終止。但不是從裏面。

+1

你確實知道你忽略了你的參數,而是搜索「DAP」嗎? –

+0

謝謝,這不是問題,因爲'DAP'是我想斷開連接的用戶。 – cheeesus

回答

2

首先,你不應該在你傳遞給EXECUTE IMMEDIATE SQL語句中的分號。這會導致ORA-00911錯誤。

其次,它總是有幫助的打印出你執行它之前,你已經建立了動態​​SQL語句。額外的分號可能是唯一的錯誤。或者可能有其他錯誤。如果您可以看到您構建的SQL語句(並單獨執行),而不是僅僅查看構建語句的代碼,那麼這些錯誤將不可避免地更易於調試。

+0

謝謝,請參閱編輯。 – cheeesus

+1

@cheeesus - 你仍然有分號。如果您剪切並粘貼生成的SQL語句並以交互方式運行它,則會出現錯誤,因爲雙引號不正確。您的第一次生成單引號的嘗試是正確的方法,最後錯誤地使用了分號。 –