From one of my client ,it was required to send the message to application users (on Windows) for specific events by the database server. I used the simple msg (Win command) for this purpose , example given below :
Create the OSCommand Java Class
Create the Wrapper Function to use Java class
Connect as SYS or SYSTEM and grant the following privilege to the desired user
Test it
Set Serverout On
Declare
x Varchar2(2000);
vCMD varchar2(100);
vUser varchar2(50);
vMsg varchar2(1000);
vWait integer := 10;
Begin
vCMD := 'cmd /c msg /TIME:'||vWait;
vUser := ' Inam ';
vMsg := 'Test Msg by PL/SQL';
x := OSCommand_Run(vCMD||vUser||vMsg);
DBMS_OUTPUT.Put_Line(x);
End;
/
Create procedure for your easiness, if you want
create or replace procedure proc_send_msg(pMsg varchar2)
is
x Varchar2(2000);
vCMD varchar2(100);
vUser varchar2(50);
vMsg varchar2(1000);
vWait integer := 10;
Begin
vCMD := 'cmd /c msg /TIME:'||vWait;
vUser := ' Inam ';
vMsg := pMsg;
x := OSCommand_Run(vCMD||vUser||vMsg);
DBMS_OUTPUT.Put_Line(x);
End;
/
Even you can schedule it if required
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => X
,what => 'FOR REC IN (select OSUSER,USERNAME,TERMINAL,MACHINE,STATUS,STATE,LAST_CALL_ET,
''Dear ''||OSUSER||'' You are inactive for the last half an hour'' msg
from v$session
where last_call_et > 1800) LOOP
proc_send_msg(msg);
END LOOP; '
,next_date => to_date('06/26/2012 12:00:33','mm/dd/yyyy hh24:mi:ss')
,interval => 'SYSDATE+2/1440 '
,no_parse => FALSE
);
:JobNumber := to_char(X);
END;
/
Some sample msg command usage:
msg /SERVER:Inam-PC inam salam -- machine name then username and message
msg Inam "salam" -- username and message
msg Inam /TIME:10 "Salam" -- with message delay in seconds
msg /TIME:10 /SERVER:Inam-PC inam Salam
Note:
If you get any error (code) while running the msg command, you can check the error code as below
net helpmsg ERRORCODE
eg;net helpmsg 5
Create the OSCommand Java Class
CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "OSCommand" AS
import java.io.*;
public class OSCommand{
public static String Run(String Command){
try{
Runtime.getRuntime().exec(Command);
return("0");
}
catch (Exception e){
System.out.println("Error running command: " + Command +
"\n" + e.getMessage());
return(e.getMessage());
}
}
}
/
import java.io.*;
public class OSCommand{
public static String Run(String Command){
try{
Runtime.getRuntime().exec(Command);
return("0");
}
catch (Exception e){
System.out.println("Error running command: " + Command +
"\n" + e.getMessage());
return(e.getMessage());
}
}
}
/
Create the Wrapper Function to use Java class
CREATE or REPLACE FUNCTION OSCommand_Run(Command IN STRING)
RETURN VARCHAR2 IS
LANGUAGE JAVA
NAME 'OSCommand.Run(java.lang.String) return int';
/
RETURN VARCHAR2 IS
LANGUAGE JAVA
NAME 'OSCommand.Run(java.lang.String) return int';
/
Connect as SYS or SYSTEM and grant the following privilege to the desired user
Execute dbms_java.grant_permission( 'SCOTT','SYS:java.io.FilePermission','<>','execute');
execute dbms_java.grant_permission( 'SCOTT','SYS:java.lang.RuntimePermission','writeFileDescriptor','*' );
execute dbms_java.grant_permission( 'SCOTT','SYS:java.lang.RuntimePermission','readFileDescriptor','*' );
commit;
execute dbms_java.grant_permission( 'SCOTT','SYS:java.lang.RuntimePermission','writeFileDescriptor','*' );
execute dbms_java.grant_permission( 'SCOTT','SYS:java.lang.RuntimePermission','readFileDescriptor','*' );
commit;
Test it
Set Serverout On
Declare
x Varchar2(2000);
vCMD varchar2(100);
vUser varchar2(50);
vMsg varchar2(1000);
vWait integer := 10;
Begin
vCMD := 'cmd /c msg /TIME:'||vWait;
vUser := ' Inam ';
vMsg := 'Test Msg by PL/SQL';
x := OSCommand_Run(vCMD||vUser||vMsg);
DBMS_OUTPUT.Put_Line(x);
End;
/
Create procedure for your easiness, if you want
create or replace procedure proc_send_msg(pMsg varchar2)
is
x Varchar2(2000);
vCMD varchar2(100);
vUser varchar2(50);
vMsg varchar2(1000);
vWait integer := 10;
Begin
vCMD := 'cmd /c msg /TIME:'||vWait;
vUser := ' Inam ';
vMsg := pMsg;
x := OSCommand_Run(vCMD||vUser||vMsg);
DBMS_OUTPUT.Put_Line(x);
End;
/
Even you can schedule it if required
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => X
,what => 'FOR REC IN (select OSUSER,USERNAME,TERMINAL,MACHINE,STATUS,STATE,LAST_CALL_ET,
''Dear ''||OSUSER||'' You are inactive for the last half an hour'' msg
from v$session
where last_call_et > 1800) LOOP
proc_send_msg(msg);
END LOOP; '
,next_date => to_date('06/26/2012 12:00:33','mm/dd/yyyy hh24:mi:ss')
,interval => 'SYSDATE+2/1440 '
,no_parse => FALSE
);
:JobNumber := to_char(X);
END;
/
Some sample msg command usage:
msg /SERVER:Inam-PC inam salam -- machine name then username and message
msg Inam "salam" -- username and message
msg Inam /TIME:10 "Salam" -- with message delay in seconds
msg /TIME:10 /SERVER:Inam-PC inam Salam
Note:
If you get any error (code) while running the msg command, you can check the error code as below
net helpmsg ERRORCODE
eg;net helpmsg 5
No comments:
Post a Comment