Est-il possible de lancer un shell UNIX (ou une commande système) à partir d'une procédure stockée?
Je suis en Oracle 8.1.7 sous SUN Solaris
Est-il possible de lancer un shell UNIX (ou une commande système) à partir d'une procédure stockée?
Je suis en Oracle 8.1.7 sous SUN Solaris
Pour exécuter une commande système depuis du PL/SQL nous allons utiliser une classe Java. La création d'un classe java exécutable en PL/SQL passe par trois étapes : tout d'abord on créé la Java Source, ensuite on publie la spécification d'appel de cette source et enfin on accorde les privilèges nécessaires à l'exécution de cette classe Java.
Donc on va tout d'abord créer la classe Java permettant d'exécuter une commande système:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Host" AS import java.io.*; public class Host { public static void executeCommand(String command) { try { String[] finalCommand; if (isWindows()) { finalCommand = new String[4]; finalCommand[0] = "C:\\windows\\system32\\cmd.exe"; finalCommand[1] = "/y"; finalCommand[2] = "/c"; finalCommand[3] = command; } else { finalCommand = new String[3]; finalCommand[0] = "/bin/sh"; finalCommand[1] = "-c"; finalCommand[2] = command; } final Process pr = Runtime.getRuntime().exec(finalCommand); new Thread(new Runnable() { public void run() { try { BufferedReader br_in = new BufferedReader(new InputStreamReader(pr.getInputStream())); String buff = null; while ((buff = br_in.readLine()) != null) { System.out.println("Process out :" + buff); try {Thread.sleep(100); } catch(Exception e) {} } br_in.close(); } catch (IOException ioe) { System.out.println("Exception caught printing process output."); ioe.printStackTrace(); } } }).start(); new Thread(new Runnable() { public void run() { try { BufferedReader br_err = new BufferedReader(new InputStreamReader(pr.getErrorStream())); String buff = null; while ((buff = br_err.readLine()) != null) { System.out.println("Process err :" + buff); try {Thread.sleep(100); } catch(Exception e) {} } br_err.close(); } catch (IOException ioe) { System.out.println("Exception caught printing process error."); ioe.printStackTrace(); } } }).start(); } catch (Exception ex) { System.out.println(ex.getLocalizedMessage()); } } public static boolean isWindows() { if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) return true; else return false; } }; / show errors java source "Host"
Ensuite on publie la spécification d'appel de cette classe en utilisant une procédure PL/SQL pour la "wrapper":
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 CREATE OR REPLACE PROCEDURE Host_Command (p_command IN VARCHAR2) AS LANGUAGE JAVA NAME 'Host.executeCommand (java.lang.String)'; /
Enfin, les permissions nécessaire doivent être données par l'utilisateur SYS pour que le JServer puisse accèder aux fichiers su système:
On doit se reconnecter pour activer les privilèges.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 EXEC Dbms_Java.Grant_Permission('SCHEMA-NAME', 'java.io.FilePermission', '<>', 'read ,write, execute, delete'); EXEC Dbms_Java.Grant_Permission('SCHEMA-NAME', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', ''); EXEC Dbms_Java.Grant_Permission('SCHEMA-NAME', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');
Ensuite on lance notre commande
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 SET SERVEROUTPUT ON SIZE 1000000 CALL DBMS_JAVA.SET_OUTPUT(1000000); BEGIN Host_Command (p_command => 'move C:\test1.txt C:\test2.txt'); END; /
Lors du lancement de la première commande CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Host" AS....., j'obtiens le message suivant :
ERROR at line 1:
ORA-29547: Java system class not available: oracle/aurora/rdbms/Compiler
Je suppose que je dois faire quelque chose pour pouvoir utiliser cette commande, je ne sais malheureusemebt pas quoi....
arg je crois que tu as pas du installer le support java. Je vais voir si je trouve plus d'info
pour installer la jvm oracle, tu dois executer le fichier initjvm.sql
qui se trouve sous :
$ORACLE_HOME\javavm\install\initjvm.sql
tu risues d'avoir des souci avec les aprametre java pool du fichier init.ora.
Si c le cad augmente les...en esperant que tu es assez de RAM..car la JVM est assez gurmande.
Bon courage
ps : initjvm.sql doit etre lance sous SYS
Effectivemment, j'ai eu quelques problèmes de java_pool_size, large_pool_size, shared_pool_size.
J'ai pris les valeurs suivantes :
java_pool_size = 50M
large_pool_size = 45M
shared_pool_size=70M
J'ai ensuite positionner le LD_LIBRARY_PATH64 sur $ORACLE_HOME/lib64 dans l'environnement UNIX.
Petite explication dans la procédure de grant :
EXEC Dbms_Java.Grant_Permission('SCHEMA-NAME', 'java.io.FilePermission', '<>', 'read ,write, execute, delete');
le '<>' doit être remplacer par le répertoire dans lequel se trouve le shell ou la commande (exemple bin/sh pour la commande ls).
Ensuite tout roule...
Merci à tous
comment executer une commande système sous oracle si on n'a pas la jvm et que le dba ne peut l'installer ??
je dis à mon chef de projet que c'est pas possible ou c'est une blague ?![]()
Si, c'est possible :
http://www.developpez.net/forums/vie...highlight=host
es tu sur que je peux pas mettre ma commande sys. direct dans ma proc ?
car elle nécessite un paramètre qu'elle récupère dans le LOOP.
On peut pas faire un truc de ce style :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 --envoi du mail via une commande système à destination de BLAT.EXE --ho blat fichier -t fctn_GetMailRecipient(LyceeNum) -f moi@domaine.fr -s \"Le sujet\";
pourquoi s'évertuer à ne pas utiliser utl_snmp ?![]()
Envoyé par plaineR
au temps pour moi![]()
Ca tu peux le faire puisque tout est en commentairesEnvoyé par c_moi_c_moi
![]()
Plus sérieusement, c'est quoi ton ho ?
on m'a dit que ca permettait d'exécuter une commande système dans une proc. stock., syntaxe de la sorte suivante :
ho commde systeme
A mon avis, c'est l'abréviation de la commande host de SQL*Plus.
ne fonctionne pas dans une procédure stockée.
où dois je donc lancer ma commande sql*plus ?
Sous SQL*Plus, non ?
STOP AU SQUAT DE SUJET !!!!
c_moi_c_moicontinue dans TON sujet !
Bonjour aux connaisseurs,
![]()
je voudrais sous Unix/Oracle pouvoir lancer un script Shell dans lequel figurerait des requêtes SQL du genre :
UPDATE UC10 SET TICONN = '0001-01-01-00.00.00'
DELETE FROM CO22 WHERE CDUTIL IN ( SELECT CDUTIL FROM UC10 WHERE TYUTIL = 'A')
DELETE FROM UC10 WHERE TYUTIL = 'A'
Est-ce possible et comment faire ?![]()
Merci de me donner les syntaxes de lancement des requêtes SQL en Shell.
![]()
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager