Вызов shell из Oracle альтернативный метод

    После прочтения статьи Вызов shell из Oracle

    Я решил поделиться своим решением данной проблемы. Для решения задачи применяется Javaб поэтому на Oracle XE данный солюшен работать не будет.

    Зато данное решение кросс-платформенно — работает на всех ОС с которыми мне приходилось сталкиваться.
    А так же позволяет видеть результаты выполнения внешней команды в DBMS_OUTPUT.

    Приступим к реализации:

    Шаг 1: создаем на базе исходник на Java.

    import java.lang.*;
    import java.io.*;
    import java.sql.SQLException;

    public class Host {

    public static void executeCommand (String command) throws SQLException,IOException
    {
    #sql {
    begin
    DBMS_JAVA.set_output (10000000);
    end;
    };
    String uFullCommand = ""; String nameOS = System.getProperty(«os.name»);

    if ((nameOS.toLowerCase()).indexOf(«lin») != -1)
    {
    uFullCommand = "/bin/sh" + " -c " + command;
    }
    else if ((nameOS.toLowerCase()).indexOf(«win») != -1)
    {
    uFullCommand = "%systemroot%\\system32\\cmd.exe" + " /y" + " /c " + command;
    }
    else if ((nameOS.toLowerCase()).indexOf(«nix») != -1)
    {
    uFullCommand = command;
    }
    else
    {
    uFullCommand = command;
    }

    Runtime rt = Runtime.getRuntime();
    Process p = rt.exec(uFullCommand);
    BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));

    String line = null;
    while ((line = in.readLine()) != null)
    {
    System.out.println(line);
    }
    }
    };


    Шаг 2: оборачиваем в PL/SQL.

    CREATE OR REPLACE
    PROCEDURE host_command_proc (p_command IN VARCHAR2) AS
    LANGUAGE JAVA
    NAME 'Host.executeCommand (java.lang.String)';
    /


    Пример вызова:

    begin
    host_command_proc («ls /tmp»);
    end;


    И да идея данного решения заимствована у Тома Кайта.
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 10

      0
      кто бы еще объяснил — зачем?
        0
        drunken,
        если честно сам не пользуюсь :)) считаю это экстримизмом :)))

        Но солюшен был, человек писал значит кому-то нужно, так почему не поделиться?
          0
          dbms_scheduler.create_job
          (
          job_name => l_job_name,
          job_type => 'EXECUTABLE',
          job_action => '/home/user/script.sh',
          number_of_arguments => 2,
          start_date => sysdate,
          auto_drop => true
          );
          dbms_scheduler.set_job_argument_value(l_job_name, 1, p_argument1);
          dbms_scheduler.set_job_argument_value(l_job_name, 2, p_argument2);

          А так не проще?
            0
            если есть возможность получить лог вывода команды — то проще
            0
            Уп-с… Хм… Как то такой проблемы не было, а так обычно в темповый файл валю…
              0
              я это сделал когда работал в банке с суровыми админами, которые верили, что разрабам нечего делать на операционной системе даже тестовых серверов и прав нам недавали, а благодаря этому можно были из скул консоли работать как с обычным шелом — тут же видеть результаты выполнения.

              Во всех остальных случаях Вы безусловно правы и этот велосипед ненужен :) он только для дев инстансов, но обладает своим шармом
              0
              Скажите, а в XE можно из триггера просто писать информацию в log_YYYY_MM_DD.txt?
              Просто заводить отдельную таблицу нерационально — информации много, а ковырять лог требуется максимум раз в полгода.
              Если да, то как это можно сделать?
                0
                PACKAGE BODY backtrace
                IS
                g_path CONSTANT VARCHAR2 (1000) := 'LOGS_HOME'; — directory

                PROCEDURE put_line (p_value IN VARCHAR2)
                IS
                BEGIN
                IF UTL_FILE.is_open (g_file)
                THEN
                UTL_FILE.fclose (g_file);
                END IF;
                UTL_FILE.put_line (p_value, v_tmp);
                IF UTL_FILE.is_open (g_file)
                THEN
                UTL_FILE.fclose (g_file);
                END IF;
                EXCEPTION
                WHEN OTHERS
                THEN
                NULL;
                END;
                  0
                  спасибо, попробую.
                0
                Мде… я уже публиковал на хабре почти два года назад свое решение c таймаутом и пайплайнед, но оно выпилилось, когда отрубили ссылки: xt-r.com/2010/11/oracle-svn-git-etc.html

                Only users with full accounts can post comments. Log in, please.