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
1 comment:
A very practical and insightful approach to integrating operating-system messaging with Oracle PL/SQL. The use of Java stored procedures to execute the Windows msg command, along with session-based monitoring and job scheduling, provides a useful solution for delivering timely notifications to database users. This is a great example of combining Oracle capabilities with OS-level functionality to address real-world administration and monitoring requirements.
signature massage Lahore
leather gift items
concrete resurfacing moorebank
Post a Comment