网上曾多次询问过这个问题,但我在Google上找到的答案都无法解决我的问题。
我想创建一个杀死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"
如果我在存储过程之外执行此语句,它运行正常并且会话被终止。但不是来自内心。
答案 0 :(得分:2)
首先,在传递给EXECUTE IMMEDIATE
的SQL语句中不应该有分号。这会导致ORA-00911错误。
其次,在执行之前打印出您构建的动态SQL语句总是有帮助的。额外的分号可能是唯一的错误。或者可能存在其他错误。如果您可以看到已构建的SQL语句(并单独执行)而不是仅仅查看构建语句的代码,那么这些错误将不可避免地更容易调试。
答案 1 :(得分:0)
您可以使用以下过程:
{
CREATE PROCEDURE kill_user_session (users IN VARCHAR2)
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 = users AND p.addr(+) = s.paddr;
BEGIN
FOR session_rec IN get_sessions
LOOP
BEGIN
stmt := 'ALTER SYSTEM KILL SESSION ''' || session_rec.sid || ',' || session_rec.ser || '''' || ' IMMEDIATE';
--dbms_output.put_line(stmt);
BEGIN
EXECUTE IMMEDIATE stmt;
--EXCEPTION WHEN others THEN
-- dbms_output.put_line('Error killing session: ' || stmt);
-- dbms_output.put_line(SQLERRM);
EXCEPTION
WHEN OTHERS
THEN
-- You probably need to log this error properly here.
-- I will just re-raise it.
CONTINUE;
END;
END;
END LOOP;
END;
/
}