Reputation: 14435
This has been asked several times on the web, but none of the answers I found on Google could solve my problem.
I'd like to create a stored procedure that kills Oracle sessions. The only parameter the procedure accepts is the user name of the owner of the sessions to kill.
This is my attempt:
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;
/
If I execute it like this
exec kill_user_session('myuser');
I get an error:
ERROR at line 1:
ORA-00911: invalid character
ORA-06512: at "SYSTEM.KILL_USER_SESSION", line 17
ORA-06512: at line 1
If I change line 17 to
stmt := 'ALTER SYSTEM KILL SESSION "' || session_rec.sid || ',' || session_rec.ser || '"';
then I get
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
I have granted the following rights to SYSTEM:
GRANT SELECT ON v$session TO SYSTEM;
GRANT ALTER SYSTEM TO SYSTEM;
But that didn't help.
EDIT: I added a dbms_output.putline
to print out the stmt
variable before executing it. Here's an example:
ALTER SYSTEM KILL SESSION "34,91"
If I execute this statement outside of the stored procedure, it runs fine and the session is killed. But not from inside.
Upvotes: 1
Views: 13642
Reputation: 1
You can use this procedure:
{
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;
/
}
Upvotes: 0
Reputation: 231671
First off, you shouldn't have a semicolon in the SQL statement you pass to EXECUTE IMMEDIATE
. That would cause the ORA-00911 error.
Second, it is always helpful to print out the dynamic SQL statement that you've built before you execute it. The extra semicolon may be the only error. Or there may be other errors. Those errors will inevitably be easier to debug if you can see the SQL statement that you've built (and execute it separately) rather than just looking at the code that builds the statement.
Upvotes: 3