Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.tools -> Re: Executing external programs from a database procedure.
I've done this by using the UTL_FILE package to write a Unix shell script on the host system. Then, I have a C program that monitors a directory for one of these files. When it finds the file it uses the SYSTEM command to execute it. If your host has a decent scheduling tool on it, one that can monitor a directory, then you don't need to write your own C program.
Here's some sample code. I pulled out a few installation-specific things, but it should still work OK. At least it might be enough to get you started.
CREATE OR REPLACE PROCEDURE sp_write_script (p_emp_id IN VARCHAR2, p_command IN VARCHAR2, p_o_err OUT NUMBER, p_o_msg OUT VARCHAR2, p_sql_err OUT NUMBER, p_sql_msg OUT VARCHAR2) ISThe contents
/* This routine creates a shell script file on the Unix server.
of the file are specified in the second parameter.
The name of the file created is p_emp_id_xxxxxxxxx.req where xxxxxxxxx is
a unique temporary file name generated by Unix. Thus, if the employee id passed to this routine is 'billybob', the file created would be
named something like this:
billybob_baaa13569.req
Parameters: 1. Employee ID. Used to help prevent duplicate file IDs. 2. Unix command(s) to execute. 3. On return, result of routine. 0 : No errors. 1 : Warning. -1 : An error occurred. 4. On return, current error or step message. NULL if no error. 5. On return, SQLCODE from last SQL statement when there was an error; otherwise 0. 6. On return, SQLERRM from last SQL statement when therewas an error; otherwise 0.
v_output_file_handle UTL_FILE.FILE_TYPE; v_output_directory VARCHAR2 (512) := 'a directory specified by the initialization parameter utl_file_dir';
v_output_file VARCHAR2 (512); e_edit_excep EXCEPTION;
IF p_emp_id IS NULL THEN
p_o_msg := 'Required emp_id parameter missing'; raise e_edit_excep;
p_o_msg := 'Building output file name'; v_output_file := RTRIM (LTRIM (p_emp_id)) || '_' || sf_tmpname || '.req';
p_o_msg := 'Opening output file ' || v_output_directory || '/' || v_output_file;
v_output_file_handle := UTL_FILE.FOPEN (v_output_directory, v_output_file, 'w');
p_o_msg := 'Writing to output file ' || v_output_directory || '/' || v_output_file;
UTL_FILE.PUT_LINE (v_output_file_handle, '#!/usr/bin/sh'); UTL_FILE.PUT_LINE (v_output_file_handle, p_command); UTL_FILE.PUT_LINE (v_output_file_handle, 'return 0'); p_o_msg := 'Closing output file ' || v_output_directory || '/' ||v_output_file;
UTL_FILE.FCLOSE (v_output_file_handle); p_o_err := 0; p_o_msg := NULL;
WHEN OTHERS THEN
IF UTL_FILE.IS_OPEN (v_output_file_handle) = TRUE THEN UTL_FILE.FCLOSE (v_output_file_handle); END IF; p_o_err := -1; p_sql_err := SQLCODE; p_sql_msg := SQLERRM;
/*
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <dirent.h> #include <limits.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h>
/***************************************************************
***************************************************************/
/* Prototypes */
char *match_first_file (char p_directory_to_search[],
char p_characters_to_match[], int p_starting_position); int copy_file (char p_source_file[], char p_dest_file[], char p_permissions[4]); int move_file (char p_base_file_name[], char p_source_dir_name[], char p_dest_dir_name[]); int log_message (char p_file[], char p_message[]);
/***************************************************************
***************************************************************/
int main(int argc, char *argv[])
{
char l_parm0 [MAXNAMLEN], l_parm1 [PATH_MAX], l_parm2 [MAXNAMLEN], l_parm3 [4], l_parm4 [4], l_parm5 [PATH_MAX], l_parm6 [4], l_full_orig_file_name [MAXNAMLEN], l_base_file_name [MAXNAMLEN], l_exec_file_name [MAXNAMLEN], l_temp_file_name [MAXNAMLEN], l_sys_cmd [MAXNAMLEN], l_msg [400]; int l_return_value, l_result_value;
l_return_value = 0;
strcpy (l_parm0, argv [0]);
log_message (l_parm0, "Starting script_launcher");
if (argc != 7)
{
/* We require all parameters. */ log_message (l_parm0, "Missing parameters"); printf ("\nUsage: this_program_name directory_to_monitor characters_to_match"); printf ("\n starting_position_to_search (0=at end, - 1=anywhere)"); printf ("\n permissions_of_copied_script (XXX=don't care)"); printf ("\n subdirectory_for_used_files sleep_time_after_finding_file"); l_return_value = -1;
strcpy (l_parm1, argv [1]); strcpy (l_parm2, argv [2]); strcpy (l_parm3, argv [3]); strcpy (l_parm4, argv [4]); strcpy (l_parm5, argv [5]); strcpy (l_parm6, argv [6]);
while (l_return_value == 0)
{
/* Find a file to process. */ strcpy (l_base_file_name, match_first_file (l_parm1, l_parm2,atoi (l_parm3)));
if (strncmp (l_base_file_name, "MFF_ERR", 7) == 0) { sprintf (l_msg, "Error in match_first_file=%s. parm1=%s parm2=%s parm3=%s", l_base_file_name, l_parm1, l_parm2, l_parm3); log_message (l_parm0, l_msg); l_return_value = -1; break; } if (strcmp (l_base_file_name, NULL) == 0) { /* No files found. Wait to make another pass. */ sleep (10); /* Insert a break here to have this program make only a single pass. */ continue; } /* At this point we know we found a file to process. */ sleep (atoi (l_parm6)); sprintf (l_full_orig_file_name, "%s/%s", l_parm1, l_base_file_name); sprintf (l_msg, "Processing file %s", l_full_orig_file_name); log_message (l_parm0, l_msg); /* Copy the file we found as one of our own files since the execute attribute on the original file might not be enabled and we might not be able to change it. */ strcpy (l_exec_file_name, l_full_orig_file_name); strcat (l_exec_file_name, ".sh"); l_result_value = copy_file (l_exec_file_name,l_full_orig_file_name, l_parm4);
if (l_result_value != 0) { sprintf (l_msg, "Error in copy_file=%d\n", l_result_value); log_message (l_parm0, l_msg); l_return_value = -1; break; } /* Move the original file to the specified directory. */ sprintf (l_temp_file_name, "%s/%s", l_parm1, l_parm5); if (move_file (l_base_file_name, l_parm1, l_temp_file_name) != 0) { log_message (l_parm0, "Error in file rename1"); l_return_value = -1; break; } /* Execute our copy of the job. */ system (l_exec_file_name); /* Move our copy of the job to the specified directory. */ sprintf (l_temp_file_name, "%s/%s", l_parm1, l_parm5); strcat (l_base_file_name, ".sh"); if (move_file (l_base_file_name, l_parm1, l_temp_file_name) != 0) { log_message (l_parm0, "Error in file rename2"); l_return_value = -1; break; } /* Insert a break here to have this program process only asingle file. */
}
return l_return_value;
} /* End of main */
/***************************************************************
***************************************************************/containing
/*
* This routine searches the directory named in its first parameter * for the first file name with characters that match those specified in * the second parameter. * This routine returns a pointer to the character string
char *match_first_file (char p_directory_to_search[],
char p_characters_to_match[], int p_starting_position){
#define MFF_TOO_MANY_CHARACTERS_TO_MATCH "MFF_ERR2" #define MFF_BAD_DIR_OPEN "MFF_ERR1" #define MFF_DIR_NAME_TOO_LONG "MFF_ERR3" #define MFF_FIND_MATCH_ANYWHERE p_starting_position == -1 #define MFF_FIND_MATCH_AT_END p_starting_position == 0
DIR *l_directory_pointer;
struct dirent *l_directory_entry;
struct stat l_file_status;
int l_number_of_characters_to_match, l_starting_position, l_ending_position, l_filename_position, l_filename_length, l_compare_string_position; char l_compare_string [MAXNAMLEN];
/* When p_starting_position is not zero, we want to extract
strlen (p_characters_to_match) characters from the file name starting at p_starting_position and compare this to p_characters_to_match. When p_starting_position is zero, we want to extract strlen (p_characters_to_match) characters from the file name starting at strlen (filename) - strlen (p_characters_to_match) */
l_number_of_characters_to_match = strlen (p_characters_to_match); l_starting_position = p_starting_position - 1;
if (strlen (p_directory_to_search) > PATH_MAX) {
return MFF_DIR_NAME_TOO_LONG;
}
if (! MFF_FIND_MATCH_ANYWHERE)
{
if (l_number_of_characters_to_match > MAXNAMLEN) { /* If the character string to match is longer than the longest possible file name. */ return MFF_TOO_MANY_CHARACTERS_TO_MATCH; }
}
if ((l_directory_pointer = opendir (p_directory_to_search)) == NULL) {
return MFF_BAD_DIR_OPEN;
}
while ((l_directory_entry = readdir (l_directory_pointer)) != NULL) {
strcpy (l_found_name, NULL); l_filename_length = strlen (l_directory_entry->d_name); if (l_filename_length > MAXNAMLEN) { /* Don't process any file names that are too long. */ continue; } if (strlen (p_directory_to_search) + strlen (l_directory_entry- >d_name) > PATH_MAX) { /* Don't process any path/file name combinations that are too long. */ continue; } /* Now we need to determine the type of the file we found. */ strcpy (l_full_path_name, p_directory_to_search); strcat (l_full_path_name, "/"); strcat (l_full_path_name, l_directory_entry->d_name); stat (l_full_path_name, &l_file_status); if ((l_file_status.st_mode & S_IFMT) == S_IFDIR) { /* Don't process any directories. */ continue; } if (MFF_FIND_MATCH_ANYWHERE) { /* If we want to match characters anywhere in the file name we don't need to do much work. */ if (strstr (l_directory_entry->d_name, p_characters_to_match)) { strcpy (l_found_name, l_directory_entry->d_name); break; } else { continue; } } if (l_number_of_characters_to_match > l_filename_length) { /* If we are requested to match more characters than there are in the file name, skip the file. */ continue; } if (MFF_FIND_MATCH_AT_END) { /* When the starting position we were given is zero, we have to figure out what it really is, based upon the length of the file name. */ l_starting_position = l_filename_length - l_number_of_characters_to_match; } l_ending_position = l_starting_position +l_number_of_characters_to_match - 1;
if (l_ending_position > l_filename_length) { /* If we end up with an ending position past the end of the file name then skip the file. */ continue; } l_filename_position = l_starting_position; l_compare_string_position = 0; l_compare_string [0] = '\0'; /* Now extract the characters from the file name that we will compare to the string to search for. */ while (l_directory_entry->d_name [l_filename_position] != '\0' && l_filename_position <= l_ending_position && l_compare_string_position < MAXNAMLEN && l_filename_position < MAXNAMLEN) { l_compare_string [l_compare_string_position] = l_directory_entry->d_name [l_filename_position]; l_filename_position++; l_compare_string_position++; } l_compare_string [l_compare_string_position] = '\0'; if (strcmp (p_characters_to_match, l_compare_string) == 0) { strcpy (l_found_name, l_directory_entry->d_name); break; }
} /* while ((l_directory_entry = readdir (l_directory_pointer)) !=
NULL) */
closedir (l_directory_pointer);
return l_found_name;
} /* End of match_first_file */
/***************************************************************
***************************************************************/
/*
* This routine copies the file named in the first parameter as
int copy_file (char p_dest_file[], char p_source_file[], char p_permissions[4])
FILE *l_input_file,
*l_output_file;
char l_sys_cmd [MAXNAMLEN];
int l_c;
if ((l_input_file = fopen (p_source_file, "r")) == NULL) {
return -1;
}
if ((l_output_file = fopen (p_dest_file, "w")) == NULL) {
return -2;
}
while ((l_c = getc (l_input_file)) != EOF) {
putc (l_c, l_output_file);
}
if (fclose (l_input_file) == EOF)
{
return -3;
}
if (fclose (l_output_file) == EOF)
{
return -4;
}
if (strcmp (p_permissions, "XXX") != 0) {
strcpy (l_sys_cmd, "chmod "); strcat (l_sys_cmd, p_permissions); strcat (l_sys_cmd, " "); strcat (l_sys_cmd, p_dest_file); system (l_sys_cmd);
return 0;
} /* End of copy_file */
/***************************************************************
***************************************************************/*
/*
* This routine moves the file specified from one directory to * another. * * Parameters: * 1. Base name of file to be moved. * 2. Source directory name. * 3. Destination directory name. * * Return values: * 0 : No errors * -1 : Error in rename function.
int move_file (char p_base_file_name[], char p_source_dir_name[], char p_dest_dir_name[])
char l_source_name [MAXNAMLEN], l_dest_name [MAXNAMLEN], l_sys_cmd [MAXNAMLEN];
DIR *l_directory_pointer;
/* Check to see that the destination directory exists. */ if ((l_directory_pointer = opendir (p_dest_dir_name)) == NULL) {
/* Create the destination directory. */ strcpy (l_sys_cmd, "mkdir "); strcat (l_sys_cmd, p_dest_dir_name); system (l_sys_cmd); strcpy (l_sys_cmd, "chmod 777 "); strcat (l_sys_cmd, p_dest_dir_name); system (l_sys_cmd);
strcpy (l_source_name, p_source_dir_name); strcat (l_source_name, "/"); strcat (l_source_name, p_base_file_name); strcpy (l_dest_name, p_dest_dir_name);strcat (l_dest_name, "/");
if (rename (l_source_name, l_dest_name) != 0) {
return -1;
}
closedir (l_directory_pointer);
return 0;
} /* End of move_file */
/***************************************************************
***************************************************************/*
/*
* This routine logs the message passed to it to the file * script_launcher.log located in the directory specified * by the LOG environment variable. * * Parameters: * 1. Base name of file to log to. * 2. Message to be logged. * * Return values: * 0 : No errors * -1 : LOG environment variable not set.
int log_message (char p_file[], char p_message[]) {
FILE *l_output_file;
char l_log_file_name [MAXNAMLEN], l_str_date_now [9], l_str_time_now [14], l_msg [400];
int l_time_len;
struct tm *local;
time_t l_time_now;
if ((getenv("LOG")) == NULL)
{
return -1;
}
l_time_now=time(NULL);
local=localtime(&l_time_now);
strftime(l_str_date_now,100,"%04Y/%02m/%02d",local);
strftime(l_str_time_now,100,"%02H:%02M:%02S:00",local);
strcpy (l_log_file_name, getenv ("LOG")); strcat (l_log_file_name, "/"); strcat (l_log_file_name, p_file); strcat (l_log_file_name, ".log");
sprintf (l_msg,"%s %s %s", l_str_date_now, l_str_time_now, p_message);
if (strlen (l_msg) > 395)
{
l_msg [399] = '\0';
}
umask(0);
l_output_file = fopen (l_log_file_name, "a");
fprintf (l_output_file, "%s\n", l_msg);
fclose (l_output_file);
return 0;
} /* End of log_message */
/***************************************************************
***************************************************************/
In article <KDJ%5.109856$yO2.3247911_at_telenews.teleline.es>, "Ant" <anorfri_at_teleline.es> wrote:
> Hello !!! > > Now I have a new (and big for me) problem. It's because I must runan exe
> file from Oracle? > > Thanks > > Ant > >
Sent via Deja.com
http://www.deja.com/
Received on Tue Dec 19 2000 - 08:33:39 CST
![]() |
![]() |