-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathp_admin.sql
216 lines (202 loc) · 6.95 KB
/
p_admin.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
create or replace package p_admin is
-- Kill a session specified by SID (V$SESSION).
procedure killSession( tSid in number );
-- Kill all sessions except system and a current one.
procedure killAllSessions;
-- Kill sessions of all users who are logged in with their accounts (OSUSER != SYSTEM).
procedure killDevelopersSessions;
-- Kill sessions of current user (OSUSER).
procedure killUserSessions;
-- Kill Test Window (PL/SQL Developer) sessions of current user (OSUSER).
procedure killUserTestSessions;
-- Kill a job (USER_JOBS) specified by identifier.
procedure killJob( tJob in number );
-- Kill a job if it's running and schedule it to launch at min( sysdate + tMax, max( sysdate + tMin, NEXT_DATE + tIncr ) ).
-- Default behavior: kill a job and schedule it to launch in 10 minutes.
procedure pauseJob( tJob in number, tMin in number default 1 / 144, tMax in number default null, tIncr in number default null );
-- Kill all jobs and schedule them to launch later.
procedure pauseAllJobs( tMin in number default 1 / 144, tMax in number default null, tIncr in number default null );
-- Kill jobs selected by a mask and schedule them to launch later.
procedure pauseJobsLike( tLikeCondition in varchar2, tMin in number default 1 / 144, tMax in number default null, tIncr in number default null, tJob in number default null );
-- Return current session id (SID).
function getSessionId return number;
-- Return current job id (JOB from USER_JOBS), or null if the function is called outside a job.
function getJobId return number;
end;
/
create or replace package body p_admin is
-- Kill a session specified by SID (V$SESSION).
procedure killSession( tSid in number ) is
tSpidn number;
tInstanceName varchar2( 16 );
begin
select p.SPID
into tSpidn
from V$SESSION s,
V$PROCESS p
where s.SID = tSid
and s.PADDR = p.ADDR
-- The caller of this procedure is allowed to kill only his sessions.
and ( s.USERNAME = user
-- Allow the owner of this procedure (usually some kind of a DBA schema) to kill any session.
or s.USERNAME != 'SYS'
and user = sys_context( 'userenv', 'current_schema' ) );
if dbms_utility.port_string like '%WIN%' then
select INSTANCE_NAME
into tInstanceName
from V$INSTANCE;
runCommand( 'orakill.exe ' || tInstanceName || ' ' || tSpidn );
else
runCommand( 'kill -9 ' || tSpidn );
end if;
exception
when NO_DATA_FOUND then
null;
when OTHERS then
raise;
end;
-- Kill all sessions except system and a current one.
procedure killAllSessions is
tAudSid number := sys_context( 'userenv', 'sessionid' );
begin
for rec in ( select SID
from V$SESSION
where AUDSID not in ( 0, tAudSid )
and SCHEMANAME != 'SYS' ) loop
killSession( rec.SID );
end loop;
end;
-- Kill sessions of all users who are logged in with their accounts (OSUSER != SYSTEM).
procedure killDevelopersSessions is
tAudSid number := sys_context( 'userenv', 'sessionid' );
begin
for rec in ( select SID
from V$SESSION
where AUDSID not in ( 0, tAudSid )
and SCHEMANAME != 'SYS'
and OSUSER != 'SYSTEM' ) loop
killSession( rec.SID );
end loop;
end;
-- Kill sessions of current user (OSUSER).
procedure killUserSessions is
tAudSid number := sys_context( 'userenv', 'sessionid' );
tOsUser varchar2( 30 ) := sys_context( 'userenv', 'os_user' );
begin
for rec in ( select SID
from V$SESSION
where AUDSID not in ( 0, tAudSid )
and SCHEMANAME != 'SYS'
and OSUSER = tOsUser ) loop
killSession( rec.SID );
end loop;
end;
-- Kill Test Window (PL/SQL Developer) sessions of current user (OSUSER).
procedure killUserTestSessions is
tAudSid number := sys_context( 'userenv', 'sessionid' );
tOsUser varchar2( 30 ) := sys_context( 'userenv', 'os_user' );
begin
for rec in ( select SID
from V$SESSION
where AUDSID not in ( 0, tAudSid )
and SCHEMANAME != 'SYS'
and OSUSER = tOsUser
and lower( ACTION ) like '%test%' ) loop
killSession( rec.SID );
end loop;
end;
-- Kill a job (USER_JOBS) specified by identifier.
procedure killJob( tJob in number ) is
tSid number;
begin
select SID
into tSid
from V$LOCK
where TYPE = 'JQ'
and ID2 = tJob;
killSession( tSid );
exception
when NO_DATA_FOUND then
raise_application_error( -20001, 'Job ' || tJob || ' is not running' );
when OTHERS then
raise;
end;
-- Kill a job if it's running and schedule it to launch at min( sysdate + tMax, max( sysdate + tMin, NEXT_DATE + tIncr ) ).
-- Default behavior: kill a job and schedule it to launch in 10 minutes.
procedure pauseJob( tJob in number, tMin in number default 1 / 144, tMax in number default null, tIncr in number default null ) is
begin
pauseJobsLike( '%', tMin, tMax, tIncr, tJob );
end;
-- Kill all jobs and schedule them to launch later.
procedure pauseAllJobs( tMin in number default 1 / 144, tMax in number default null, tIncr in number default null ) is
begin
pauseJobsLike( '%', tMin, tMax, tIncr );
end;
-- Kill jobs selected by a mask and schedule them to launch later.
procedure pauseJobsLike( tLikeCondition in varchar2, tMin in number default 1 / 144, tMax in number default null, tIncr in number default null, tJob in number default null ) is
tRunning number( 1 );
tNextDate date;
begin
loop
tRunning := 0;
for rec in ( select JOB, WHAT, INTERVAL, NEXT_DATE
from USER_JOBS
where WHAT like tLikeCondition
and ( tJob is null
or JOB = tJob ) ) loop
tNextDate := rec.NEXT_DATE + nvl( tIncr, 0 );
if tMin is not null then
tNextDate := greatest( tNextDate, sysdate + tMin );
end if;
if tMax is not null then
tNextDate := least( tNextDate, sysdate + tMax );
end if;
begin
dbms_job.change( job => rec.JOB,
what => rec.WHAT,
next_date => tNextDate,
interval => rec.INTERVAL );
commit;
exception
when OTHERS then
if sqlerrm not like '%PLS-00905%' then
raise;
end if;
end;
begin
killJob( rec.JOB );
tRunning := 1;
exception
when OTHERS then
if sqlcode != -20001 then
raise;
end if;
end;
end loop;
commit;
exit when tRunning = 0;
dbms_lock.sleep( 1 );
end loop;
commit;
end;
-- Return current session id (SID).
function getSessionId return number is
begin
return sys_context( 'userenv', 'sessionid' );
end;
-- Return current job id (JOB from USER_JOBS), or null if the function is called outside a job.
function getJobId return number is
ret number;
begin
select ID2
into ret
from V$LOCK
where TYPE = 'JQ'
and SID = sys_context( 'userenv', 'sessionid' );
return ret;
exception
when NO_DATA_FOUND then
return null;
end;
end;
/