Pls_integer vs. number

PLS_INTEGER values require less storage than NUMBER values. Also, PLS_INTEGER operations use machine arithmetic, so they are faster than NUMBER and BINARY_INTEGER operations, which use library arithmetic.Having this, if i add two numbers, one of NUMBER data type and one of pls_integer (or simple_integer) data type, where will this operation be done? In the library arithmetic or machine arithmetic?

What is your Oracle version? Although BINARY_INTEGER has been semi-deprecated since Oracle 7, in 10g it's the same thing as PLS_INTEGER. You might also look up SIMPLE_INTEGER.
Tom's point is that you should be aware of implicit casting, as (for example) SQL statements like SELECT INTO will return the 'fat' NUMBER/INTEGER types and so selecting into a PLS_INTEGER involves a conversion step at runtime, unless the PL/SQL compiler spots it and internally replaces it with a SQL-compatible type anyway (not sure if it does that but I wouldn't be surprised). Also as he mentions, it's not often that the theoretical performance advantages of PLS_INTEGER result in a measurable difference in practice.
However there will often be places in pure PL/SQL code, such as perhaps a counter that you increment, where PLS_INTEGER (or even SIMPLE_INTEGER) is the logical choice even if there is no significant performance advantage.
Also I would always use an integer type (either INTEGER, which is just a constrained NUMBER, or one of the leaner PL/SQL types) if I was dealing with values that should logically be integers, to make it completely clear that there could be no fractional values.

Similar Messages

  • Calling report from form. Need PDF output

    I am calling a report from a form using RUN_PRODUCT. I need to display the form in PDF format. When the user clicks the button in the form to run the report, acrobat reader should open up and the report displayed there. Please help.
    Thanks

    Thanks for the response. The first part worked. I am able to get the output in PDF format. In the 2nd part where I want to open acrobat and display the output, I am having some trouble with the code. When I compile, it says
    win_api_environment.read_registry must be declared. Is there some package I need to attach?
    Also, in the After reports trigger, how do I pass vFile (I am assuming this is the PDF file name)?
    Thanks
    The first thing you'll want to do is pass parameters to the report IE DESTYPE, DESNAME and DESFORMAT where these could be FILE, 'c:\temp\report' and PDF.
    Then, you can try this piece of code I wrote (with some help from other people at Metalink and here) sometime back. Now, I call it from forms, but in your case, you'd have to run it in the after report trigger. Since with RUN_PRODUCT you don't know when the report is finished, if you did it from the form, it wouldn't work correctly.
    PROCEDURE OPEN_PDF(vFile IN VARCHAR2)
    IS
    vcServerApp varchar2(40);
    vcServerTag varchar2(600);
    vcCommand varchar2(2000);
    iArgPos pls_integer;
    dummy NUMBER;
    BEGIN
    -- 1 get the Server App for .PDF files
    vcServerApp := win_api_environment.read_registry('HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\.PDF','',true);
    -- 2 get the executable
    vcServerTag := 'HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\'||
    vcServerApp||'\SHELL\OPEN\COMMAND';
    vcCommand:= win_api_environment.read_registry(vcServerTag,'',true);
    -- 3 Sort out how to specify the Filename
    iArgPos:= instr(vcCommand,'%1');
    if iArgPos = 0 then --no substitution Var on the command line
    vcCommand := vcCommand||' '||vFile;
    else
    vcCommand := substr(vcCommand,1,(iArgPos-1))||
    vFile||substr(vcCommand,(iArgPos+2));
    end if;
    -- 4 Run using Winexec (or Host if preferred).
    win_api_shell.winexec(vcCommand);
    EXCEPTION
    when no_data_found then
    abortt('Acrobat Reader was not found! Please consult with your help desk to install it and try again.','N');
    END;
    Chad
    I am calling a report from a form using RUN_PRODUCT. I need to display the form in PDF format. When the user clicks the button in the form to run the report, acrobat reader should open up and the report displayed there. Please help.
    Thanks

  • Convert ORA_FFI to WEBUTIL_C_API to print locally

    I am trying to figure out how to convert this package to WEBUTIL_C_API to be able to print to a users local printer (EPSON slip printer)... ANY help would be appreciated...
    PACKAGE EPSON_SLIP_PRINTER_INTERFACE IS
    * This package provides functions to interact with the EPSON
    * TM-U295 slip printers.
    * The OPEN_PRINTER function must be called to obtain a printer ID.
    * This printer ID can then be used when calling other functions
    * that require a printer to be specified.
    * NOTE that the printer ID is only valid within the same thread
    * that called the OPEN_PRINTER function.
    * Brendan Rickey 2004-JAN-09
    -- AVAILABLE PRINTERS
    CHEQUE_PRINTER     VARCHAR2(50) := 'Generic / Text Only droite';
    INVOICE_PRINTER     VARCHAR2(50) := 'Generic / Text Only left';
    -- ERROR CODES
    -- Some of the provided functions return a NUMBER value that may hold
    -- an error code (negative number).
    -- These are the possible error codes:
    SUCCESS                    NUMBER := 0;     --no error
    ERR_TYPE               NUMBER := -10;     --parameter type error
    ERR_OPENED               NUMBER := -20; --printer already opened
    ERR_NO_PRINTER     NUMBER := -30;     --the printer driver does not exist
    ERR_NO_TARGET          NUMBER := -40;     --no printer found (could of off, faulty, unsupported)
    ERR_NO_MEMORY          NUMBER := -50;     --insufficient memory
    ERR_HANDLE               NUMBER := -60;     --invalid printer ID
    ERR_TIMEOUT               NUMBER := -70;     --time out error
    ERR_ACCESS               NUMBER := -80;     --cannot read/write to printer (printing in progress)
    ERR_PARAM               NUMBER := -90;     --parameter error
    ERR_OFFLINE               NUMBER := -110;     --printer was opened in offline state.  Status must be changed to online.
    ERR_NOT_EPSON          NUMBER := -120;     --printer is not an EPSON printer
    * INITIALIZE
    * Initializes the interface between Forms and the EPSON library (call before any other function in the package).
    * Returns:
    * TRUE if the library is registered successfully,
    * FALSE otherwise (library not found etc...)
    function INITIALIZE return BOOLEAN;
    * OPEN_PRINTER
    * Obtains a handle on the specified EPSON slip printer (either CHEQUE_PRINTER or INVOICE_PRINTER).
    * Returns:
    *           a printer ID for the specified printer (greater than 0)
    *           an error code on failure (less than 0):
    * ERR_TYPE, ERR_OPENED, ERR_NO_PRINTER, ERR_NO_TARGET, ERR_NO_MEMORY, ERR_PARAM
    function OPEN_PRINTER (p_printer_name IN VARCHAR2) return NUMBER;
    * CLOSE_PRINTER
    * Releases the handle on the specified printer.
    * Returns:
    *           0 on success
    *           ERR_HANDLE on failure
    function CLOSE_PRINTER (p_printer_id IN NUMBER) return NUMBER;
    * IS_PAPER_OUT
    * Tests if there is no paper in the printer.
    * Returns:
    *           1 if there is no paper in the printer, 0 if paper is in the printer
    *           ERR_HANDLE or ERR_PARAM on failure.
    function IS_PAPER_OUT (p_printer_id IN NUMBER) return NUMBER;
    * PRINT_TEXT
    * Prints the specified text to the specified printer.
    * Returns:
    *           0 on success
    *           ERR_HANDLE, ERR_ACCESS, ERR_OFFLINE, ERR_NOT_EPSON, or ERR_PARAM on failure.
    function PRINT_TEXT (p_printer_id IN NUMBER, p_text IN VARCHAR2) return NUMBER;
    * RELEASE_PAPER
    * Performs the Release function on the specified printer.
    * Returns:
    *           0 on success
    *           ERR_HANDLE, ERR_ACCESS, ERR_OFFLINE, ERR_NOT_EPSON, or ERR_PARAM on failure.
    function RELEASE_PAPER (p_printer_id IN NUMBER) return NUMBER;
    /* PRIVATE FUNCTIONS
    function BiOpenMonPrinter(arg0 in PLS_INTEGER,
    arg1 in out VARCHAR2)
    return PLS_INTEGER;
    function BiCloseMonPrinter(arg0 in PLS_INTEGER)
    return PLS_INTEGER;
    function BiGetStatus(arg0 in PLS_INTEGER,
    arg1 in out PLS_INTEGER)
    return PLS_INTEGER;
    function BiDirectIO(arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER)
    return PLS_INTEGER;
    function BiDirectIOEx(arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER,
    arg7 in PLS_INTEGER)
    return PLS_INTEGER;
    END;
    PACKAGE BODY EPSON_SLIP_PRINTER_INTERFACE IS
    v_msg_b VARCHAR2(20);
    v_EPSON_LIBRARY_OK BOOLEAN:= FALSE;
    --ORA_FFI function handles and library handle
    lh_EpsStmApi ora_ffi.libHandleType;                    --DLL library handle
    fh_BiOpenMonPrinter ora_ffi.funcHandleType;          --DLL function handle
    fh_BiCloseMonPrinter ora_ffi.funcHandleType;     --DLL function handle
    fh_BiGetStatus ora_ffi.funcHandleType;               --DLL function handle
    fh_BiDirectIO ora_ffi.funcHandleType;               --DLL function handle
    fh_BiDirectIOEx ora_ffi.funcHandleType;               --DLL function handle
    --constant
    ASB_SLIP_BOF     PLS_INTEGER := 4*power(16,5);     --BOF printer status flag 0x00400000
    c_release_code      CHAR(2) := CHR(27)||CHR(113);     --ESC+q, to release the paper
    -------PRIVATE FUNCTIONS--------
    * Brendan Rickey 2004-JAN-09
    * The following are functions that are required to interface with the
    * EPSON StatusAPI DLL (C library) though ORA_FFI.
    * The following describes the DLL functions that are made available
    * through this ORA_FFI implementation:
    Function Purpose
    BiOpenMonPrinter Get a handle on a printer.
    Parameters
    p_Type --int: 1 if p_Name is a port, 2 if a printer name.
    ,p_Name --varchar2: the port of printer name to open.
    Return printer identifier number (>0) on success, < 0 on failure.
    BiCloseMonPrinter Close the monitor on the printer.
    Parameters
    p_Handle --int: The numerical printer handle returned from BiOpenMonPrinter.
    Return 0 on success, < 0 on failure.
    BiGetStatus Returns the status of the printer.
    Parameters     
    p_Handle --int: The numerical printer handle returned from BiOpenMonPrinter.
    ,p_Status OUT --long: The status of the printer (use AND bitwise operator to test for statuses).
    Return 0 on success, < 0 on failure.
    BiDirectIO Sends data to and Reads data from the printer. Use BiDirectIOEx if more that 255 chars are to be written/read.
    Parameters
    p_Handle --int: The numerical printer handle returned from BiOpenMonPrinter.
    ,p_WriteLen --short: The length of the command/data being sent to the printer (max 255).
    ,p_WriteCmd --varchar2: The command/data to send to the printer.
    ,p_ReadLen --short: The length of the data to be read from the printer (max 255)
    (Use 0 if no data is to be read).
    ,p_ReadBuff OUT --varchar2: The buffer where the the data read from the printer is stored.
    ,p_Timeout --long: write/read time out in msecs.
    ,p_NullTerminate --short: 0 => reading of data from printer is performed until time out or length of p_ReadLen is reached.
    1 => reading is finished at thepoint when a NULL is received from the printer. ReadLen must have a value.
    Return 0 on success, < 0 on failure.
    BiDirectIOEx Sends data to and Reads data from the printer (handles larger quantities of write/read data).
    Parameters
    p_Handle --int: The numerical printer handle returned from BiOpenMonPrinter.
    ,p_WriteLen --long: The length of the command/data being sent to the printer.
    ,p_WriteCmd --varchar2: The command/data to send to the printer.
    ,p_ReadLen --long: The length of the data to be read from the printer (Use 0 if no data is to be read).
    ,p_ReadBuff OUT --varchar2: The buffer where the the data read from the printer is stored.
    ,p_Timeout --long: write/read time out in msecs.
    ,p_NullTerminate --short: 0 => reading of data from printer is performed until time out or length of p_ReadLen is reached.
    1 => reading is finished at thepoint when a NULL is received from the printer. ReadLen must have a value.
    ,p_Option --short: 0 => prevents Automatic Status Back (ASB) during execution of this function (as does BiDirectIO).
    1 => does not disable Automatic Status Back (ASB).
    Return 0 on success, < 0 on failure.
    function icd_BiOpenMonPrinter(funcHandle in ora_ffi.funcHandleType, arg0 in PLS_INTEGER,
    arg1 in out VARCHAR2)
    return PLS_INTEGER;
    pragma interface(c, icd_BiOpenMonPrinter, 11265);
    function BiOpenMonPrinter(arg0 in PLS_INTEGER,
    arg1 in out VARCHAR2)
    return PLS_INTEGER is
    begin
    return(icd_BiOpenMonPrinter(fh_BiOpenMonPrinter,
    arg0,
    arg1));
    end;
    function icd_BiCloseMonPrinter(funcHandle in ora_ffi.funcHandleType, arg0 in PLS_INTEGER)
    return PLS_INTEGER;
    pragma interface(c, icd_BiCloseMonPrinter, 11265);
    function BiCloseMonPrinter(arg0 in PLS_INTEGER)
    return PLS_INTEGER is
    begin
    return(icd_BiCloseMonPrinter(fh_BiCloseMonPrinter,
    arg0));
    end;
    function icd_BiGetStatus(funcHandle in ora_ffi.funcHandleType, arg0 in PLS_INTEGER,
    arg1 in out PLS_INTEGER)
    return PLS_INTEGER;
    pragma interface(c, icd_BiGetStatus, 11265);
    function BiGetStatus(arg0 in PLS_INTEGER,
    arg1 in out PLS_INTEGER)
    return PLS_INTEGER is
    begin
    return(icd_BiGetStatus(fh_BiGetStatus,
    arg0,
    arg1));
    end;
    function icd_BiDirectIO(funcHandle in ora_ffi.funcHandleType, arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER)
    return PLS_INTEGER;
    pragma interface(c, icd_BiDirectIO, 11265);
    function BiDirectIO(arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER)
    return PLS_INTEGER is
    begin
    return(icd_BiDirectIO(fh_BiDirectIO,
    arg0,
    arg1,
    arg2,
    arg3,
    arg4,
    arg5,
    arg6));
    end;
    function icd_BiDirectIOEx(funcHandle in ora_ffi.funcHandleType, arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER,
    arg7 in PLS_INTEGER)
    return PLS_INTEGER;
    pragma interface(c, icd_BiDirectIOEx, 11265);
    function BiDirectIOEx(arg0 in PLS_INTEGER,
    arg1 in PLS_INTEGER,
    arg2 in out VARCHAR2,
    arg3 in out PLS_INTEGER,
    arg4 in out VARCHAR2,
    arg5 in PLS_INTEGER,
    arg6 in PLS_INTEGER,
    arg7 in PLS_INTEGER)
    return PLS_INTEGER is
    begin
    return(icd_BiDirectIOEx(fh_BiDirectIOEx,
    arg0,
    arg1,
    arg2,
    arg3,
    arg4,
    arg5,
    arg6,
    arg7));
    end;
    --------PUBLIC FUNCTIONS--------
    function INITIALIZE return BOOLEAN IS
    BEGIN
    --When this is the first package function called, code in the package's
    --body is executed and sets v_EPSON_LIBRARY_OK.
    RETURN v_EPSON_LIBRARY_OK;
    END;
    function OPEN_PRINTER (p_printer_name IN VARCHAR2) return NUMBER IS
         v_printer                    PLS_INTEGER;
         v_printer_name     VARCHAR2(50) := p_printer_name;
         v_name_type           PLS_INTEGER := 2; --use printer Name to specify printer     
    BEGIN
         /* Open a monitor for the printer */
         v_printer := BiOpenMonPrinter(v_name_type,v_printer_name);
         RETURN v_printer;
    END;
    function CLOSE_PRINTER (p_printer_id IN NUMBER) return NUMBER IS
    v_return PLS_INTEGER;
    BEGIN
    /* CLOSE the printer monitor */
         v_return := BiCloseMonPrinter(p_printer_id);
         RETURN v_return;
    END;
    function IS_PAPER_OUT (p_printer_id IN NUMBER) return NUMBER IS
         v_return          PLS_INTEGER;
         v_status          PLS_INTEGER := -123456;
    BEGIN
         /* Test if paper is in the printer by first getting the status (a binary integer) */
         v_return := BiGetStatus(p_printer_id,v_status);
         IF v_return <> 0 THEN
              RETURN v_return;
         ELSE
         --Test for BOF status flag
         IF WIN_API_BITOP.BITWISE_AND(v_status,ASB_SLIP_BOF) = ASB_SLIP_BOF THEN
              RETURN 1; --paper out
         ELSE
              RETURN 0; --paper in
         END IF;
         END IF;
    END;
    function PRINT_TEXT (p_printer_id IN NUMBER, p_text IN VARCHAR2) return NUMBER IS
    v_return          PLS_INTEGER;
    v_text               VARCHAR2(2000) := p_text;
    v_text_len          PLS_INTEGER;                    --number of characters to be printed
    v_read_len      PLS_INTEGER := 0;               --number of characters to be read from the printer
    v_read_buff      VARCHAR2(255) := NULL;          --not used: holds characters read from the printer
    v_timeout      PLS_INTEGER := 1000;          --not used: amount of time to wait for response (msecs)
         v_nullTerm          PLS_INTEGER := 0;               --not used: 0 means read until reached v_read_len or v_timeout
         -- 1 means read until NULL received from printer
         v_option          PLS_INTEGER := 0;           --0 means do not answer other requests while printing
                                                                --1 means do not stop answering other requests while printing
    BEGIN
         --Get the number of chars to be printed and then print.
         v_text_len := length(p_text);
         v_return := BiDirectIOEx(p_printer_id,
         v_text_len,
         v_text,
         v_read_len,
         v_read_buff,
         v_timeout,
         v_nullTerm,
         v_option);
         --Ignore timeout(-70) errors, otherwise return error
         IF v_return = -70 THEN
              v_return := 0;     
         END IF;
         RETURN v_return;
    END;
    function RELEASE_PAPER (p_printer_id IN NUMBER) return NUMBER IS
    BEGIN
    /* Release the paper by sending the release escape code to the printer */
         RETURN PRINT_TEXT(p_printer_id, c_release_code);
    END;
    -----END OF FUNCTION IMPLEMENTATIONS-----
    BEGIN
    * Load the EPSON printer driver's StatusAPI library.
    * Create an ORA_FFI interface to the library by doing the following for each desired function:
    *          1- Create a handle on the function,
    *          2- Register the return value,
    *          3- Register the arguments/parameters in the correct order.
    lh_EpsStmApi := ora_ffi.load_library('', 'EpsStmApi.DLL');
    IF Ora_Ffi.Is_Null_Ptr(lh_EpsStmApi) THEN
         AFC_MESSAGES('I','MAIN-0020','E',v_msg_b);
         v_EPSON_LIBRARY_OK := FALSE;
    ELSE
    fh_BiOpenMonPrinter := ora_ffi.register_function(lh_EpsStmApi, 'BiOpenMonPrinter', ora_ffi.c_std);
    ora_ffi.register_return(fh_BiOpenMonPrinter, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiOpenMonPrinter, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiOpenMonPrinter, ora_ffi.c_char_ptr, ora_ffi.pls_varchar2);
    fh_BiCloseMonPrinter := ora_ffi.register_function(lh_EpsStmApi, 'BiCloseMonPrinter', ora_ffi.c_std);
    ora_ffi.register_return(fh_BiCloseMonPrinter, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiCloseMonPrinter, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    fh_BiGetStatus := ora_ffi.register_function(lh_EpsStmApi, 'BiGetStatus', ora_ffi.c_std);
    ora_ffi.register_return(fh_BiGetStatus, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiGetStatus, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiGetStatus, ora_ffi.c_long_ptr, ora_ffi.pls_pls_integer);
    fh_BiDirectIO := ora_ffi.register_function(lh_EpsStmApi, 'BiDirectIO', ora_ffi.c_std);
    ora_ffi.register_return(fh_BiDirectIO, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_short, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_char_ptr, ora_ffi.pls_varchar2);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_short_ptr, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_char_ptr, ora_ffi.pls_varchar2);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_long, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIO, ora_ffi.c_short, ora_ffi.pls_pls_integer);
    fh_BiDirectIOEx := ora_ffi.register_function(lh_EpsStmApi, 'BiDirectIOEx', ora_ffi.c_std);
    ora_ffi.register_return(fh_BiDirectIOEx, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_int, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_long, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_char_ptr, ora_ffi.pls_varchar2);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_long_ptr, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_char_ptr, ora_ffi.pls_varchar2);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_long, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_short, ora_ffi.pls_pls_integer);
    ora_ffi.register_parameter(fh_BiDirectIOEx, ora_ffi.c_short, ora_ffi.pls_pls_integer);
    v_EPSON_LIBRARY_OK := TRUE;
    END IF;
    EXCEPTION
         WHEN OTHERS THEN
              AFC_MESSAGES('I','MAIN-0021','E',v_msg_b);
              v_EPSON_LIBRARY_OK := FALSE;
    END;

    Hi Duncan,
    Thanks for the response. Beyond the problem you pointed out I found that the "open server" command is requiring a window handle parameter, even though it isn't used by the program. I talked with Oracle Support and it turns out that even if the window handle isn't used, it's existence makes it not work with the current version of webutil.
    The program I am working with also has a COM interface, so I decided to back up and redo the interface using webutil OLE2. I've got it working now, just a little more polishing to do.
    Thanks again for the help.
    Mark

  • If you need to FTP with PL/SQL...

    If you need to perform FTP from within PL/SQL and your database version has the UTL_TCP package, here is a free package you can use. The source code is hopefully documented well enough for you to tell what's going on and how to use the functions. Suggestions on improving the code are welcome, and I can provide limited support via email for what I've written, but I would encourage anyone who uses the code to modify/fix it according to their needs. If you modify the code, I respectfully request that you leave intact the authorship and note comments at the beginning of the package.
    Please note that I have not rigorously tested this code, but it has successfully transferred files in both directions in the limited tests that I have performed.
    -- Copy the code below and run it in your favorite SQL editor --
    CREATE OR REPLACE PACKAGE FTP IS
    Simplified FTP client API using UTL_TCP package
    Author: Alan Wessman, Brigham Young University
    Note: This FTP client attempts to adhere to the protocol and advice found at:
    http://cr.yp.to/ftp.html
    No warranties are made regarding the correctness of this code.
    Notes:
    1. Most of these functions will raise UTL_TCP.NETWORK_ERROR if the connection
    is not open or is reset during the network transaction. They will also
    raise VALUE_ERROR if the server response is ill-formed or a buffer is
    too small to hold data. (Most buffers in this package are defined as
    VARCHAR2(32767) to avoid size limitations; reduce this if memory overhead
    is a concern.)
    2. "Verbose mode" can be enabled/disabled by changing the default value of
    the vDebug variable in the package body. Setting vDebug to TRUE will
    cause a session transcript to be output to DBMS_OUTPUT.
    3. The following is an example of how this package might be used:
    declare
    c utl_tcp.connection;
    vresp varchar2(32767);
    vbuf varchar2(32767);
    vresp_code number;
    vremote_host varchar2(32) := 'some.hostname.com';
    vusername varchar2(8) := 'username';
    vpassword varchar2(8) := 'password';
    begin
    dbms_output.put_line( 'Opening session...' );
    vresp_code := ftp.open_session( c,
    vremote_host,
    vusername,
    vpassword,
    vresp,
    5 );
    vresp_code := ftp.put( c,
    '/home/somebody',
    'local.test',
    'remote.test',
    vresp );
    vresp_code := ftp.remote_command( c, 'CHMOD 660 remote.test' );
    vresp_code := ftp.chdir( c, '/home/somebody/subdir' );
    vresp_code := ftp.pwd( c );
    vresp_code := ftp.get( c,
    '/home/somebody',
    'new_file.test',
    'another_remote_file.test',
    vresp );
    vresp_code := ftp.close_session( c );
    dbms_output.put_line( 'Closed session.' );
    exception
    when others then dbms_output.put_line( sqlcode || ':' || sqlerrm );
    end;
    Function: Open_Session
    Description: Begins an FTP session with the remote server.
    Parameters:
    conn OUT parameter that contains the connection info; to be passed
    in to subsequent commands to maintain session state.
    host Name or IP address of remote server
    username User ID to use for login
    password Password to use for login
    response OUT parameter; buffer for server replies
    timeout_secs Number of seconds for TCP timeout. Pass in NULL to disable
    timeout (wait forever for responses). Pass in 0 (zero) for
    no wait.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if host parameter is incorrect or if
    some other networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    FUNCTION Open_Session( conn OUT NOCOPY UTL_TCP.Connection,
    host IN VARCHAR2,
    username IN VARCHAR2,
    password IN VARCHAR2,
    response OUT VARCHAR2,
    timeout_secs IN NUMBER DEFAULT 60 ) RETURN NUMBER;
    Function: Get
    Description: Retrieves a file on the remote server and stores its contents in
    a VARCHAR2 buffer.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    buf OUT parameter; buffer for retrieved file contents
    remote_path Pathname (including file name) indicating location of remote
    file to be retrieved
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed or buf is
    too small for file contents.
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    buf OUT VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Get
    Description: Retrieves a file on the remote server and stores its contents in
    a local file. Assumes an open file handle and does not close it.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    local_file IN OUT parameter; UTL_FILE file handle for input file. File
    is assumed to be open for writing.
    remote_path Pathname (including file name) indicating location of remote
    file to be retrieved
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed or buf is
    too small for file contents.
    May raise any of the UTL_FILE exceptions if file write operations
    fail. See UTL_FILE documentation for additional details.
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_file IN OUT UTL_FILE.File_Type,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Get
    Description: Retrieves a file on the remote server and stores its contents in
    a local file. Opens and closes local file automatically.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    local_path Pathname of local directory in which to store the retrieved
    file's contents
    local_filename Name of local file in which to store retrieved file's contents
    (creates new file or overwrites existing file)
    remote_path Pathname (including file name) indicating location of remote
    file to be retrieved
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed or buf is
    too small for file contents.
    May raise any of the UTL_FILE exceptions if file open, write, or
    close operations fail. See UTL_FILE documentation for additional
    details.
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_path IN VARCHAR2,
    local_filename IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Put
    Description: Stores data as a file on the remote server
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    buf IN parameter; contains data to upload
    remote_path Pathname (including file name) indicating location of remote
    file to be created/overwritten
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    buf IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Put
    Description: Uploads a local file to the remote server. Assumes an open file
    handle and does not close it.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    local_file IN OUT parameter; UTL_FILE file handle for input file. File
    is assumed to be open for reading.
    remote_path Pathname (including file name) indicating location of remote
    file to be created/overwritten.
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    May raise any of the UTL_FILE exceptions if file read operations
    fail. See UTL_FILE documentation for additional details.
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_file IN OUT UTL_FILE.File_Type,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Put
    Description: Uploads a local file to the remote server. Opens and closes local
    file automatically.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    local_path Pathname of local directory in which file to upload exists.
    local_filename Name of local file to upload.
    remote_path Pathname (including file name) indicating location of remote
    file to be created/overwritten.
    response OUT parameter; buffer for server replies.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    May raise any of the UTL_FILE exceptions if file open, read, or
    close operations fail. See UTL_FILE documentation for additional
    details.
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_path IN VARCHAR2,
    local_filename IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER;
    Function: Remote_Command
    Description: Sends an arbitrary command to the server via the SITE command.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    command Command and parameter(s) to send to the server, e.g.
    'CHMOD 600 foo.txt'
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    FUNCTION Remote_Command( conn IN OUT NOCOPY UTL_TCP.Connection,
    command IN VARCHAR2 ) RETURN NUMBER;
    Function: Chdir
    Description: Changes current working directory on remote server to specified
    path.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    remote_path Path on remote server to change to.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    FUNCTION Chdir( conn IN OUT NOCOPY UTL_TCP.Connection,
    remote_path IN VARCHAR2 ) RETURN NUMBER;
    Function: Pwd
    Description: Prints current working directory (on remote server) to debugging
    output if debugging is turned on.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    Return value: 0 (zero) if operation is successful; FTP error code if operation
    is not successful.
    Exceptions: May raise UTL_TCP.NETWORK_ERROR if some networking error occurs.
    May raise VALUE_ERROR if server response is ill-formed.
    FUNCTION Pwd( conn IN OUT NOCOPY UTL_TCP.Connection ) RETURN NUMBER;
    Function: Close_Session
    Description: Closes the TCP connection to the remote server.
    Parameters:
    conn IN OUT parameter that contains the connection info; to be
    passed in to subsequent commands to maintain session state.
    Return value: 0 (zero)
    Exceptions: None raised.
    FUNCTION Close_Session( conn IN OUT NOCOPY UTL_TCP.Connection ) RETURN NUMBER;
    Function: Close_All_Sessions
    Description: Closes all currently open TCP connections.
    Parameters: None.
    Return value: 0 (zero)
    Exceptions: None raised.
    FUNCTION Close_All_Sessions RETURN NUMBER;
    END FTP;
    CREATE OR REPLACE PACKAGE BODY FTP IS
    vDebug BOOLEAN := TRUE;
    FATAL_ERROR EXCEPTION;
    PROCEDURE Debug( msg IN VARCHAR2 ) IS
    BEGIN
    IF vDebug THEN
    DBMS_OUTPUT.Put_Line( msg );
    END IF;
    END Debug;
    FUNCTION Get_Response( conn IN OUT NOCOPY UTL_TCP.Connection,
    buf IN OUT VARCHAR2 ) RETURN NUMBER IS
    vLen NUMBER;
    vCode NUMBER;
    vResp VARCHAR2(32767);
    BEGIN
    vLen := UTL_TCP.READ_LINE( conn, vResp );
    Debug( vResp );
    -- If TO_NUMBER below fails, let the exception propagate to calling proc
    vCode := TO_NUMBER( SUBSTR( vResp, 1, 3 ) );
    vResp := SUBSTR( vResp, 4 );
    buf := buf || SUBSTR( vResp, 2 );
    IF SUBSTR( vResp, 1, 1 ) = '-' THEN
    LOOP
    vLen := UTL_TCP.READ_LINE( conn, vResp );
    Debug( vResp );
    <<Get_Code>>
    BEGIN
    vCode := TO_NUMBER( SUBSTR( vResp, 1, 3 ) );
    vResp := SUBSTR( vResp, 4 );
    IF SUBSTR( vResp, 1, 1 ) = ' ' THEN
    buf := buf || SUBSTR( vResp, 2 );
    EXIT;
    END IF;
    EXCEPTION WHEN VALUE_ERROR THEN NULL;
    END Get_Code;
    buf := buf || vResp;
    END LOOP;
    END IF;
    RETURN vCode;
    END Get_Response;
    FUNCTION Do_Command( conn IN OUT NOCOPY UTL_TCP.Connection,
    cmd IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vResult NUMBER := 0;
    BEGIN
    vResult := UTL_TCP.WRITE_LINE( conn, cmd );
    vResult := Get_Response( conn, response );
    RETURN vResult;
    END Do_Command;
    FUNCTION Parse_Port_Number( port_string IN VARCHAR2 ) RETURN NUMBER IS
    vResult NUMBER;
    vNew_Port_String VARCHAR2(32767);
    BEGIN
    -- This stuff parses out the port number encoding from the server reply
    -- Reply is in the format xyzh1,h2,h3,h4,p1,p2xyz
    -- xyz = possible character data (server-dependent, may not exist)
    -- h1-h4 = server IP elements; ignore since we know the host already
    -- p1,p2 = port number encoding (port number = p1 * 256 + p2 )
    vNew_Port_String := TRANSLATE( port_string, '0123456789', '0000000000' );
    vNew_Port_String := SUBSTR( port_string,
    INSTR( vNew_Port_String, '0' ),
    INSTR( vNew_Port_String, '0', -1 ) -
    INSTR( vNew_Port_String, '0' ) + 1 );
    vNew_Port_String := SUBSTR( vNew_Port_String,
    INSTR( vNew_Port_String, ',', 1, 4 ) + 1 );
    vResult := 256 * TO_NUMBER( SUBSTR( vNew_Port_String,
    1,
    INSTR( vNew_Port_String, ',' ) - 1 ) );
    vResult := vResult + TO_NUMBER( SUBSTR( vNew_Port_String,
    INSTR( vNew_Port_String, ',' ) + 1 ) );
    RETURN vResult;
    -- Allow VALUE_ERROR to propagate
    END Parse_Port_Number;
    FUNCTION Open_Session( conn OUT NOCOPY UTL_TCP.Connection,
    host IN VARCHAR2,
    username IN VARCHAR2,
    password IN VARCHAR2,
    response OUT VARCHAR2,
    timeout_secs IN NUMBER DEFAULT 60 ) RETURN NUMBER IS
    vResp_Code NUMBER;
    vGarbage NUMBER; -- For calling functions when we don't care about return val
    BEGIN
    conn := UTL_TCP.OPEN_CONNECTION( host,
    21,
    tx_timeout => timeout_secs );
    vResp_Code := Get_Response( conn, response );
    IF vResp_Code = 220 THEN
    vResp_Code := Do_Command( conn, 'USER ' || username, response );
    IF vResp_Code IN ( 331, 332 ) THEN
    vResp_Code := Do_Command( conn, 'PASS ' || password, response );
    IF vResp_Code NOT IN ( 202, 230 ) THEN
    RAISE FATAL_ERROR;
    END IF;
    ELSE
    RAISE FATAL_ERROR;
    END IF;
    END IF;
    vResp_Code := Do_Command( conn, 'TYPE I', response );
    Debug( 'Logged into ' || conn.remote_host || ' at port ' || conn.remote_port );
    RETURN 0;
    EXCEPTION
    WHEN FATAL_ERROR THEN
    Debug( 'Fatal error opening session:' );
    Debug( ' Code: ' || vResp_Code );
    Debug( ' Response: ' || response );
    vGarbage := Close_Session( conn );
    RETURN vResp_Code;
    END Open_Session;
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    buf OUT VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vResp VARCHAR2(32767);
    vResp_Code NUMBER;
    vNew_Conn UTL_TCP.Connection;
    vNew_Port NUMBER;
    BEGIN
    -- do PASV
    vResp_Code := Do_Command( conn, 'PASV', response );
    IF vResp_Code = 227 THEN
    <<Switch_Port>>
    BEGIN
    vNew_Port := Parse_Port_Number( response );
    vNew_Conn := UTL_TCP.OPEN_CONNECTION( conn.remote_host,
    vNew_Port,
    tx_timeout => conn.tx_timeout );
    Debug( 'Data connection: ' || vNew_Conn.remote_host || ':' || vNew_Conn.remote_port );
    vResp_Code := Do_Command( conn, 'RETR ' || REPLACE( remote_path, CHR(12), CHR(0) ), response );
    IF vResp_Code <> 150 THEN
    RAISE FATAL_ERROR;
    END IF;
    <<Get_Download>>
    BEGIN
    LOOP
    vResp := vResp || UTL_TCP.GET_LINE( vNew_Conn, FALSE );
    END LOOP;
    EXCEPTION
    WHEN UTL_TCP.END_OF_INPUT THEN NULL;
    END Get_Download;
    vResp_Code := Close_Session( vNew_Conn );
    vResp_Code := Get_Response( conn, response );
    IF vResp_Code BETWEEN 400 AND 599 THEN
    RAISE FATAL_ERROR;
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    Debug( SQLERRM );
    RAISE FATAL_ERROR;
    END Switch_Port;
    ELSE
    RAISE FATAL_ERROR;
    END IF;
    vResp_Code := Close_Session( vNew_Conn );
    buf := vResp;
    RETURN 0;
    EXCEPTION
    WHEN FATAL_ERROR THEN
    Debug( 'Fatal error getting ' || remote_path || ':' );
    Debug( ' Code: ' || vResp_Code );
    Debug( ' Response: ' || response );
    vResp_Code := Close_Session( vNew_Conn );
    RETURN vResp_Code;
    WHEN OTHERS THEN
    Debug( vResp_Code || ': ' || SQLERRM );
    RETURN vResp_Code;
    END Get;
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_file IN OUT UTL_FILE.File_Type,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vResp VARCHAR2(32767);
    vResp_Code NUMBER := -1;
    vNew_Conn UTL_TCP.Connection;
    vNew_Port NUMBER;
    BEGIN
    -- do PASV
    vResp_Code := Do_Command( conn, 'PASV', response );
    IF vResp_Code = 227 THEN
    <<Switch_Port>>
    BEGIN
    vNew_Port := Parse_Port_Number( response );
    vNew_Conn := UTL_TCP.OPEN_CONNECTION( conn.remote_host,
    vNew_Port,
    tx_timeout => conn.tx_timeout );
    Debug( 'Data connection: ' || vNew_Conn.remote_host || ':' || vNew_Conn.remote_port );
    vResp_Code := Do_Command( conn, 'RETR ' || REPLACE( remote_path, CHR(12), CHR(0) ), response );
    IF vResp_Code <> 150 THEN
    RAISE FATAL_ERROR;
    END IF;
    <<Get_Download>>
    BEGIN
    LOOP
    vResp := UTL_TCP.GET_LINE( vNew_Conn, FALSE );
    UTL_FILE.Put( local_file, vResp );
    END LOOP;
    EXCEPTION
    WHEN UTL_TCP.END_OF_INPUT THEN NULL;
    END Get_Download;
    vResp_Code := Close_Session( vNew_Conn );
    vResp_Code := Get_Response( conn, response );
    IF vResp_Code BETWEEN 400 AND 599 THEN
    RAISE FATAL_ERROR;
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    Debug( SQLERRM );
    RAISE FATAL_ERROR;
    END Switch_Port;
    ELSE
    RAISE FATAL_ERROR;
    END IF;
    vResp_Code := Close_Session( vNew_Conn );
    RETURN 0;
    EXCEPTION
    WHEN FATAL_ERROR THEN
    Debug( 'Fatal error getting ' || remote_path || ':' );
    Debug( ' Code: ' || vResp_Code );
    Debug( ' Response: ' || response );
    vResp_Code := Close_Session( vNew_Conn );
    RETURN vResp_Code;
    WHEN OTHERS THEN
    Debug( vResp_Code || ': ' || SQLERRM );
    RETURN vResp_Code;
    END Get;
    FUNCTION Get( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_path IN VARCHAR2,
    local_filename IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vFile UTL_FILE.File_Type;
    vResult NUMBER := -1;
    BEGIN
    vFile := UTL_FILE.FOPEN( local_path, local_filename, 'w' );
    vResult := Get( conn, vFile, remote_path, response );
    UTL_FILE.FCLOSE( vFile );
    RETURN vResult;
    EXCEPTION WHEN OTHERS THEN
    IF UTL_FILE.IS_OPEN( vFile ) THEN
    UTL_FILE.FCLOSE( vFile );
    END IF;
    RAISE;
    END Get;
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    buf IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vResp VARCHAR2(32767);
    vResp_Code NUMBER;
    vNew_Conn UTL_TCP.Connection;
    vNew_Port NUMBER;
    BEGIN
    -- do PASV
    vResp_Code := Do_Command( conn, 'PASV', response );
    IF vResp_Code = 227 THEN
    <<Switch_Port>>
    BEGIN
    vNew_Port := Parse_Port_Number( response );
    vNew_Conn := UTL_TCP.OPEN_CONNECTION( conn.remote_host,
    vNew_Port,
    tx_timeout => conn.tx_timeout );
    Debug( 'Data connection: ' || vNew_Conn.remote_host || ':' || vNew_Conn.remote_port );
    vResp_Code := Do_Command( conn, 'STOR ' || REPLACE( remote_path, CHR(12), CHR(0) ), response );
    IF vResp_Code <> 150 THEN
    RAISE FATAL_ERROR;
    END IF;
    vResp_Code := UTL_TCP.WRITE_TEXT( vNew_Conn, buf );
    UTL_TCP.FLUSH( vNew_Conn );
    vResp_Code := Close_Session( vNew_Conn );
    vResp_Code := Get_Response( conn, response );
    IF vResp_Code BETWEEN 400 AND 599 THEN
    RAISE FATAL_ERROR;
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    Debug( SQLERRM );
    RAISE FATAL_ERROR;
    END Switch_Port;
    ELSE
    RAISE FATAL_ERROR;
    END IF;
    vResp_Code := Close_Session( vNew_Conn );
    response := vResp;
    RETURN 0;
    EXCEPTION
    WHEN FATAL_ERROR THEN
    Debug( 'Fatal error putting ' || remote_path || ':' );
    Debug( ' Code: ' || vResp_Code );
    Debug( ' Response: ' || response );
    vResp_Code := Close_Session( vNew_Conn );
    RETURN vResp_Code;
    WHEN OTHERS THEN
    Debug( vResp_Code || ': ' || SQLERRM );
    RETURN vResp_Code;
    END Put;
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_file IN OUT UTL_FILE.File_Type,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vResp VARCHAR2(32767);
    vResp_Code NUMBER;
    vNew_Conn UTL_TCP.Connection;
    vNew_Port NUMBER;
    vNew_Port_String VARCHAR2(32767);
    BEGIN
    -- do PASV
    vResp_Code := Do_Command( conn, 'PASV', response );
    IF vResp_Code = 227 THEN
    <<Switch_Port>>
    BEGIN
    vNew_Port := Parse_Port_Number( response );
    vNew_Conn := UTL_TCP.OPEN_CONNECTION( conn.remote_host,
    vNew_Port,
    tx_timeout => conn.tx_timeout );
    Debug( 'Data connection: ' || vNew_Conn.remote_host || ':' || vNew_Conn.remote_port );
    vResp_Code := Do_Command( conn, 'STOR ' || REPLACE( remote_path, CHR(12), CHR(0) ), response );
    IF vResp_Code <> 150 THEN
    RAISE FATAL_ERROR;
    END IF;
    <<Get_Download>>
    BEGIN
    LOOP
    UTL_FILE.Get_Line( local_file, vResp );
    vResp_Code := UTL_TCP.WRITE_LINE( vNew_Conn, vResp );
    END LOOP;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN NULL;
    END Get_Download;
    vResp_Code := Close_Session( vNew_Conn );
    vResp_Code := Get_Response( conn, response );
    IF vResp_Code BETWEEN 400 AND 599 THEN
    RAISE FATAL_ERROR;
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    Debug( SQLERRM );
    RAISE FATAL_ERROR;
    END Switch_Port;
    ELSE
    RAISE FATAL_ERROR;
    END IF;
    vResp_Code := Close_Session( vNew_Conn );
    RETURN 0;
    EXCEPTION
    WHEN FATAL_ERROR THEN
    Debug( 'Fatal error putting ' || remote_path || ':' );
    Debug( ' Code: ' || vResp_Code );
    Debug( ' Response: ' || response );
    vResp_Code := Close_Session( vNew_Conn );
    RETURN vResp_Code;
    WHEN OTHERS THEN
    Debug( vResp_Code || ': ' || SQLERRM );
    RETURN vResp_Code;
    END Put;
    FUNCTION Put( conn IN OUT NOCOPY UTL_TCP.Connection,
    local_path IN VARCHAR2,
    local_filename IN VARCHAR2,
    remote_path IN VARCHAR2,
    response OUT VARCHAR2 ) RETURN NUMBER IS
    vFile UTL_FILE.File_Type;
    vResult NUMBER;
    BEGIN
    vFile := UTL_FILE.FOPEN( local_path, local_filename, 'r' );
    vResult := Put( conn, vFile, remote_path, response );
    UTL_FILE.FCLOSE( vFile );
    RETURN vResult;
    EXCEPTION WHEN OTHERS THEN
    IF UTL_FILE.IS_OPEN( vFile ) THEN
    UTL_FILE.FCLOSE( vFile );
    END IF;
    RAISE;
    END Put;
    FUNCTION Remote_Command( conn IN OUT NOCOPY UTL_TCP.Connection,
    command IN VARCHAR2 ) RETURN NUMBER IS
    vResp_Code NUMBER;
    vResponse VARCHAR2(32767);
    BEGIN
    vResp_Code := Do_Command( conn, 'SITE ' || command, vResponse );
    IF vResp_Code BETWEEN 500 AND 599 THEN
    RETURN vResp_Code;
    END IF;
    RETURN 0;
    END Remote_Command;
    FUNCTION Chdir( conn IN OUT NOCOPY UTL_TCP.Connection,
    remote_path IN VARCHAR2 ) RETURN NUMBER IS
    vResp_Code NUMBER;
    vResponse VARCHAR2(32767);
    BEGIN
    vResp_Code := Do_Command( conn, 'CWD ' || REPLACE( remote_path, CHR(12), CHR(0) ), vResponse );
    IF vResp_Code BETWEEN 500 AND 599 THEN
    RETURN vResp_Code;
    END IF;
    RETURN 0;
    END Chdir;
    FUNCTION Pwd( conn IN OUT NOCOPY UTL_TCP.Connection ) RETURN NUMBER IS
    vResp_Code NUMBER;
    vResponse VARCHAR2(32767);
    BEGIN
    vResp_Code := Do_Command( conn, 'PWD', vResponse );
    IF vResp_Code BETWEEN 500 AND 599 THEN
    RETURN vResp_Code;
    END IF;
    RETURN 0;
    END Pwd;
    FUNCTION Close_Session( conn IN OUT NOCOPY UTL_TCP.Connection ) RETURN NUMBER IS
    BEGIN
    IF conn.remote_host IS NULL THEN
    RETURN 0;
    END IF;
    Debug( 'Closing connection on ' || conn.remote_host || ':' || conn.remote_port );
    UTL_TCP.Close_Connection( conn );
    RETURN 0;
    EXCEPTION
    WHEN UTL_TCP.NETWORK_ERROR THEN RETURN 0;
    END Close_Session;
    FUNCTION Close_All_Sessions RETURN NUMBER IS
    BEGIN
    UTL_TCP.Close_All_Connections;
    RETURN 0;
    END Close_All_Sessions;
    END FTP;

    Here's another PL/SQL package that will FTP ASCII text files. It assumes that you have proper permissions on the remote host and simply want to transfer one or more text files, not perform any other miscellaneous commands.
    Also, from what I have read, in 9i UTL_FILE supports reading and writing of binary data so an FTP client could be written to transfer either ASCII or BINARY files.
    Regards,
    Russ
    CREATE OR REPLACE PACKAGE BRNC_FTP_PKG
    AS
    * PL/SQL FTP Client
    * Created by: Russ Johnson, Braun Consulting
    * www.braunconsult.com
    * OVERVIEW
    * This package uses the standard packages UTL_FILE and UTL_TCP to perform
    * client-side FTP functionality (PUT and GET) for text files as defined in
    * the World Wide Web Consortium's RFC 959 document - http://www.w3.org/Protocols/rfc959/
    * The procedures and functions in this package allow single or multiple file transfer using
    * standard TCP/IP connections.
    * LIMITATIONS
    * Currently the API is limited to transfer of ASCII text files only. This is
    * primarily because UTL_FILE only supports text I/O, but also because the original
    * design was for creating text files from data in the Oracle database, then transferring the file to a remote host.
    * Furthermore, the API does not support SSH/Secure FTP or connection through a proxy server.
    * Keep in mind that FTP passes the username/password combo in plain text over TCP/IP.
    * DB versions - 8i (8.1.x) and above. 8.0.x may work if it has the SYS.UTL_TCP package.
    * Note: Since UTL_FILE is used for the client-side I/O, this package is also limited to
    * transfer of files that exist in directories available to UTL_FILE for read/write.
    * These directories are defined by the UTL_FILE_DIR parameter in the init.ora file.
    * USAGE
    * Three functions are available for FTP - PUT, GET, and FTP_MULTIPLE. FTP_MULTIPLE takes
    * a table of records that define the files to be transferred (filename, directory, etc.).
    * That table can have 1 record or multiple records. The PUT and GET functions are included
    * for convenience to FTP one file at a time. PUT and GET return true if the file is transferred
    * successfully and false if it fails. FTP_MULTIPLE returns true if no batch-level errors occur
    * (such as an invalid host, refused connection, or invalid login information). It also takes the
    * table of file records IN and passes it back OUT. Each record contains individual error information.
    * EXAMPLE
    * Transfer multiple files - 1 GET and 2 PUT from a Windows machine to a host (assuming UNIX here).
    * Display any errors that occur.
    * DECLARE
    *      v_username      VARCHAR2(40) := 'rjohnson';
    * v_password      VARCHAR2(40) := 'password';
    * v_hostname      VARCHAR2(255) := 'ftp.oracle.com';
    * v_error_message      VARCHAR2(1000);
    * b_put           BOOLEAN;
    * t_files      BRNC_FTP_PKG.t_ftp_rec; -- Declare our table of file records
    * BEGIN
    * t_files(1).localpath           := 'd:\oracle\utl_file\outbound';
    * t_files(1).filename           := 'myfile1.txt';
    * t_files(1).remotepath           := '/home/oracle/text_files';
    * t_files(1).transfer_mode      := 'PUT';
    * t_files(2).localpath           := 'd:\oracle\utl_file\inbound';
    * t_files(2).filename           := 'incoming_file.xml';
    * t_files(2).remotepath           := '/home/oracle/xml_files';
    * t_files(2).transfer_mode      := 'GET';
    * t_files(3).localpath           := 'd:\oracle\utl_file\outbound';
    * t_files(3).filename           := 'myfile2.txt';
    * t_files(3).remotepath      := '/home';
    * t_files(3).transfer_mode      := 'PUT';
    * b_put := BRNC_FTP_PKG.FTP_MULTIPLE(v_error_message,
    * t_files,
    * v_username,
    * v_password,
    * v_hostname);
    * IF b_put = TRUE
    * THEN
    *     FOR i IN t_files.FIRST..t_files.LAST
    *     LOOP
    * IF t_files.EXISTS(i)
    * THEN
    *      DBMS_OUTPUT.PUT_LINE(t_files(i).status||' | '||
    * t_files(i).error_message||' | '||
    * to_char(t_files(i).bytes_transmitted)||' | '||
    * to_char(t_files(i).trans_start,'YYYY-MM-DD HH:MI:SS')||' | '||
    * to_char(t_files(i).trans_end,'YYYY-MM-DD HH:MI:SS'));
    * END IF;
    *      END LOOP;
    * ELSE
    *      DBMS_OUTPUT.PUT_LINE(v_error_message);
    * END IF;
    * EXCEPTION
    * WHEN OTHERS
    * THEN
    * DBMS_OUTPUT.PUT_LINE(SQLERRM);
    * END;
    * CREDITS
    * The W3C's RFC 959 that describes the FTP process.
    * http://www.w3c.org
    * Much of the PL/SQL code in this package was based on Java code written by
    * Bruce Blackshaw of Enterprise Distributed Technologies Ltd. None of that code
    * was copied, but the objects and methods greatly helped my understanding of the
    * FTP Client process.
    * http://www.enterprisedt.com
    *     VERSION HISTORY
    * 1.0 11/19/2002 Unit-tested single and multiple transfers between disparate hosts.                                    
    * Exceptions
    ctrl_exception     EXCEPTION;
    data_exception     EXCEPTION;
    * Constants - FTP valid response codes
    CONNECT_CODE     CONSTANT PLS_INTEGER := 220;
    USER_CODE          CONSTANT PLS_INTEGER := 331;
    LOGIN_CODE          CONSTANT PLS_INTEGER := 230;
    PWD_CODE          CONSTANT PLS_INTEGER := 257;
    PASV_CODE          CONSTANT PLS_INTEGER := 227;
    CWD_CODE          CONSTANT PLS_INTEGER := 250;
    TSFR_START_CODE1     CONSTANT PLS_INTEGER := 125;
    TSFR_START_CODE2     CONSTANT PLS_INTEGER := 150;
    TSFR_END_CODE     CONSTANT PLS_INTEGER := 226;
    QUIT_CODE          CONSTANT PLS_INTEGER := 221;
    SYST_CODE          CONSTANT PLS_INTEGER := 215;
    TYPE_CODE          CONSTANT PLS_INTEGER := 200;
    * FTP File record datatype
    * Elements:
    * localpath - full directory name in which the local file resides or will reside
    * Windows: 'd:\oracle\utl_file'
    * UNIX: '/home/oracle/utl_file'
    * filename - filename and extension for the file to be received or sent
    * changing the filename for the PUT or GET is currently not allowed
    * Examples: 'myfile.dat' 'myfile20021119.xml'
    * remotepath - full directory name in which the local file will be sent or the
    * remote file exists. Should be in UNIX format regardless of FTP server - '/one/two/three'
    * filetype - reserved for future use, ignored in code
    * transfer_mode - 'PUT' or 'GET'
    * status - status of the transfer. 'ERROR' or 'SUCCESS'
    * error_message - meaningful (hopefully) error message explaining the reason for failure
    * bytes_transmitted - how many bytes were sent/received
    * trans_start - date/time the transmission started
    * trans_end - date/time the transmission ended
    TYPE r_ftp_rec IS RECORD(localpath           VARCHAR2(255),
                   filename           VARCHAR2(255),
                   remotepath      VARCHAR2(255),
                   filetype           VARCHAR2(20),
                   transfer_mode      VARCHAR2(5),
                   status           VARCHAR2(40),
                   error_message      VARCHAR2(255),
                   bytes_transmitted      NUMBER,
                   trans_start     DATE,
                   trans_end          DATE);
    * FTP File Table - used to store many files for transfer
    TYPE t_ftp_rec IS TABLE of r_ftp_rec INDEX BY BINARY_INTEGER;
    * Internal convenience procedure for creating passive host IP address
    * and port number.
    PROCEDURE CREATE_PASV(p_pasv_cmd IN VARCHAR2,
                   p_pasv_host OUT VARCHAR2,
                   p_pasv_port OUT NUMBER);
    * Function used to validate FTP server responses based on the
    * code passed in p_code. Reads single or multi-line responses.
    FUNCTION VALIDATE_REPLY(p_ctrl_con      IN OUT UTL_TCP.CONNECTION,
                   p_code      IN PLS_INTEGER,
                   p_reply      OUT VARCHAR2)
         RETURN BOOLEAN;
    * Function used to validate FTP server responses based on the
    * code passed in p_code. Reads single or multi-line responses.
    * Overloaded because some responses can have 2 valid codes.
    FUNCTION VALIDATE_REPLY(p_ctrl_con      IN OUT UTL_TCP.CONNECTION,
                   p_code1      IN PLS_INTEGER,
                   p_code2     IN PLS_INTEGER,
                   p_reply      OUT VARCHAR2)
         RETURN BOOLEAN;
    * Procedure that handles the actual data transfer. Meant
    * for internal package use. Returns information about the
    * actual transfer.
    PROCEDURE TRANSFER_ASCII(u_ctrl_con IN OUT UTL_TCP.CONNECTION,
                   p_localpath IN VARCHAR2,
                   p_filename IN VARCHAR2,
                   p_pasv_host IN VARCHAR2,
                   p_pasv_port IN PLS_INTEGER,
                   p_transfer_mode IN VARCHAR2,
                   v_status OUT VARCHAR2,
                   v_error_message OUT VARCHAR2,
                   n_bytes_transmitted OUT NUMBER,
                   d_trans_start OUT DATE,
    d_trans_end OUT DATE);
    * Function to handle FTP of many files.
    * Returns TRUE if no batch-level errors occur.
    * Returns FALSE if a batch-level error occurs.
    * Parameters:
    * p_error_msg - error message for batch level errors
    * p_files - BRNC_FTP_PKG.t_ftp_rec table type. Accepts
    * list of files to be transferred (may be any combination of PUT or GET)
    * returns the table updated with transfer status, error message,
    * bytes_transmitted, transmission start date/time and transmission end
    * date/time
    * p_username - username for FTP server
    * p_password - password for FTP server
    * p_hostname - hostname or IP address of server Ex: 'ftp.oracle.com' or '127.0.0.1'
    * p_port - port number to connect on. FTP is usually on 21, but this may be overridden
    * if the server is configured differently.
    FUNCTION FTP_MULTIPLE(p_error_msg OUT VARCHAR2,
                   p_files IN OUT t_ftp_rec,
                   p_username IN VARCHAR2,
                   p_password IN VARCHAR2,
                   p_hostname IN VARCHAR2,
                   p_port IN PLS_INTEGER DEFAULT 21)
         RETURN BOOLEAN;
    * Convenience function for single-file PUT
    * Parameters:
    * p_localpath - full directory name in which the local file resides or will reside
    * Windows: 'd:\oracle\utl_file'
    * UNIX: '/home/oracle/utl_file'
    * p_filename - filename and extension for the file to be received or sent
    * changing the filename for the PUT or GET is currently not allowed
    * Examples: 'myfile.dat' 'myfile20021119.xml'
    * p_remotepath - full directory name in which the local file will be sent or the
    * remote file exists. Should be in UNIX format regardless of FTP server - '/one/two/three'
    * p_username - username for FTP server
    * p_password - password for FTP server
    * p_hostname - FTP server IP address or host name Ex: 'ftp.oracle.com' or '127.0.0.1'
    * v_status - status of the transfer. 'ERROR' or 'SUCCESS'
    * v_error_message - meaningful (hopefully) error message explaining the reason for failure
    * n_bytes_transmitted - how many bytes were sent/received
    * d_trans_start - date/time the transmission started
    * d_trans_end - date/time the transmission ended
    * p_port - port number to connect to, default is 21
    * p_filetype - always set to 'ASCII', reserved for future use, ignored in code
    FUNCTION PUT(p_localpath IN VARCHAR2,
              p_filename IN VARCHAR2,
              p_remotepath IN VARCHAR2,
              p_username IN VARCHAR2,
              p_password IN VARCHAR2,
              p_hostname IN VARCHAR2,
              v_status OUT VARCHAR2,
              v_error_message OUT VARCHAR2,
              n_bytes_transmitted OUT NUMBER,
              d_trans_start OUT DATE,
    d_trans_end OUT DATE,
              p_port     IN PLS_INTEGER DEFAULT 21,
              p_filetype IN VARCHAR2 := 'ASCII')
         RETURN BOOLEAN;
    * Convenience function for single-file GET
    * Parameters:
    * p_localpath - full directory name in which the local file resides or will reside
    * Windows: 'd:\oracle\utl_file'
    * UNIX: '/home/oracle/utl_file'
    * p_filename - filename and extension for the file to be received or sent
    * changing the filename for the PUT or GET is currently not allowed
    * Examples: 'myfile.dat' 'myfile20021119.xml'
    * p_remotepath - full directory name in which the local file will be sent or the
    * remote file exists. Should be in UNIX format regardless of FTP server - '/one/two/three'
    * p_username - username for FTP server
    * p_password - password for FTP server
    * p_hostname - FTP server IP address or host name Ex: 'ftp.oracle.com' or '127.0.0.1'
    * v_status - status of the transfer. 'ERROR' or 'SUCCESS'
    * v_error_message - meaningful (hopefully) error message explaining the reason for failure
    * n_bytes_transmitted - how many bytes were sent/received
    * d_trans_start - date/time the transmission started
    * d_trans_end - date/time the transmission ended
    * p_port - port number to connect to, default is 21
    * p_filetype - always set to 'ASCII', reserved for future use, ignored in code
    FUNCTION GET(p_localpath IN VARCHAR2,
              p_filename IN VARCHAR2,
              p_remotepath IN VARCHAR2,
              p_username IN VARCHAR2,
              p_password IN VARCHAR2,
              p_hostname IN VARCHAR2,
              v_status OUT VARCHAR2,
              v_error_message OUT VARCHAR2,
              n_bytes_transmitted OUT NUMBER,
              d_trans_start OUT DATE,
    d_trans_end OUT DATE,
              p_port     IN PLS_INTEGER DEFAULT 21,
              p_filetype IN VARCHAR2 := 'ASCII')
         RETURN BOOLEAN;
    END BRNC_FTP_PKG;
    CREATE OR REPLACE PACKAGE BODY BRNC_FTP_PKG
    AS
    ** Create the passive host IP and port number to connect to
    PROCEDURE CREATE_PASV(p_pasv_cmd IN VARCHAR2,
                   p_pasv_host OUT VARCHAR2,
                   p_pasv_port OUT NUMBER)
    IS
         v_pasv_cmd     VARCHAR2(30) := p_pasv_cmd; --Host and port to connect to for data transfer
    n_port_dec     NUMBER;
         n_port_add     NUMBER;
    BEGIN
         p_pasv_host := REPLACE(SUBSTR(v_pasv_cmd,1,INSTR(v_pasv_cmd,',',1,4)-1),',','.');
         n_port_dec := TO_NUMBER(SUBSTR(v_pasv_cmd,INSTR(v_pasv_cmd,',',1,4)+1,(INSTR(v_pasv_cmd,',',1,5)-(INSTR(v_pasv_cmd,',',1,4)+1))));
         n_port_add := TO_NUMBER(SUBSTR(v_pasv_cmd,INSTR(v_pasv_cmd,',',1,5)+1,LENGTH(v_pasv_cmd)-INSTR(v_pasv_cmd,',',1,5)));
         p_pasv_port := (n_port_dec*256) + n_port_add;
    EXCEPTION
    WHEN OTHERS
    THEN
         --DBMS_OUTPUT.PUT_LINE(SQLERRM);
         RAISE;
    END CREATE_PASV;
    ** Read a single or multi-line reply from the FTP server and validate
    ** it against the code passed in p_code.
    ** Return TRUE if reply code matches p_code, FALSE if it doesn't or error
    ** occurs
    ** Send full server response back to calling procedure
    FUNCTION VALIDATE_REPLY(p_ctrl_con      IN OUT UTL_TCP.CONNECTION,
                   p_code      IN PLS_INTEGER,
                   p_reply      OUT VARCHAR2)
    RETURN BOOLEAN
    IS
         n_code           VARCHAR2(3) := p_code;
         n_byte_count      PLS_INTEGER;
         v_msg          VARCHAR2(255);
         n_line_count     PLS_INTEGER := 0;
    BEGIN
         LOOP
         v_msg := UTL_TCP.GET_LINE(p_ctrl_con);
         n_line_count := n_line_count + 1;
         IF n_line_count = 1
         THEN
              p_reply := v_msg;
         ELSE
              p_reply := p_reply || SUBSTR(v_msg,4);
         END IF;
         EXIT WHEN INSTR(v_msg,'-',1,1) <> 4;
         END LOOP;
    IF to_number(SUBSTR(p_reply,1,3)) = n_code
         THEN
         RETURN TRUE;
         ELSE
         RETURN FALSE;
         END IF;
    EXCEPTION
    WHEN OTHERS
    THEN
    p_reply := SQLERRM;
    RETURN FALSE;
    END VALIDATE_REPLY;
    ** Reads a single or multi-line reply from the FTP server
    ** Return TRUE if reply code matches p_code1 or p_code2,
    ** FALSE if it doesn't or error occurs
    ** Send full server response back to calling procedure
    FUNCTION VALIDATE_REPLY(p_ctrl_con      IN OUT UTL_TCP.CONNECTION,
                   p_code1      IN PLS_INTEGER,
                   p_code2     IN PLS_INTEGER,
                   p_reply      OUT VARCHAR2)
    RETURN BOOLEAN
    IS
         v_code1      VARCHAR2(3) := to_char(p_code1);
         v_code2      VARCHAR2(3) := to_char(p_code2);
         v_msg          VARCHAR2(255);
         n_line_count     PLS_INTEGER := 0;
    BEGIN
         LOOP
         v_msg := UTL_TCP.GET_LINE(p_ctrl_con);
         n_line_count := n_line_count + 1;
         IF n_line_count = 1
         THEN
              p_reply := v_msg;
         ELSE
              p_reply := p_reply || SUBSTR(v_msg,4);
         END IF;
         EXIT WHEN INSTR(v_msg,'-',1,1) <> 4;
         END LOOP;
    IF to_number(SUBSTR(p_reply,1,3)) IN(v_code1,v_code2)
         THEN
         RETURN TRUE;
         ELSE
         RETURN FALSE;
         END IF;
    EXCEPTION
    WHEN OTHERS
    THEN
    p_reply := SQLERRM;
    RETURN FALSE;
    END VALIDATE_REPLY;
    ** Handles actual data transfer. Responds with status, error message, and
    ** transfer statistics.
    ** Potential errors could be with connection or file i/o
    PROCEDURE TRANSFER_ASCII(u_ctrl_con IN OUT UTL_TCP.CONNECTION,
                   p_localpath IN VARCHAR2,
                   p_filename IN VARCHAR2,
                   p_pasv_host IN VARCHAR2,
                   p_pasv_port IN PLS_INTEGER,
                   p_transfer_mode IN VARCHAR2,
                   v_status OUT VARCHAR2,
                   v_error_message OUT VARCHAR2,
                   n_bytes_transmitted OUT NUMBER,
                   d_trans_start OUT DATE,
    d_trans_end OUT DATE)
    IS
         u_data_con          UTL_TCP.CONNECTION;
         u_filehandle          UTL_FILE.FILE_TYPE;
    v_tsfr_mode          VARCHAR2(3) := p_transfer_mode;
         v_mode               VARCHAR2(1);
    v_tsfr_cmd          VARCHAR2(10);
         v_buffer          VARCHAR2(32767);
         v_localpath          VARCHAR2(255)      := p_localpath;
         v_filename          VARCHAR2(255)      := p_filename;
         v_host               VARCHAR2(20)      := p_pasv_host;
         n_port               PLS_INTEGER      := p_pasv_port;
         n_bytes               NUMBER;
         v_msg               VARCHAR2(255);
         v_reply               VARCHAR2(1000);
         v_err_status          VARCHAR2(20) := 'ERROR';
    BEGIN
         /** Initialize some of our OUT variables **/
         v_status          := 'SUCCESS';
         v_error_message          := ' ';
         n_bytes_transmitted     := 0;
         IF UPPER(v_tsfr_mode) = 'PUT'
    THEN
         v_mode      := 'r';
         v_tsfr_cmd      := 'STOR ';
         ELSIF UPPER(v_tsfr_mode) = 'GET'
         THEN
         v_mode     := 'w';
         v_tsfr_cmd := 'RETR ';
    END IF;
         /** Open data connection on Passive host and port **/
         u_data_con := UTL_TCP.OPEN_CONNECTION(v_host,n_port);
         /** Open the local file to read and transfer data **/
         u_filehandle := UTL_FILE.FOPEN(v_localpath,v_filename,v_mode);
         /** Send the STOR command to tell the server we're going to upload a file **/
         n_bytes := UTL_TCP.WRITE_LINE(u_ctrl_con,v_tsfr_cmd||v_filename);
         IF VALIDATE_REPLY(u_ctrl_con,TSFR_START_CODE1,TSFR_START_CODE2,v_reply) = FALSE
         THEN
         RAISE ctrl_exception;
         END IF;
         d_trans_start := SYSDATE;
         IF UPPER(v_tsfr_mode) = 'PUT'
         THEN
         LOOP
              BEGIN
              UTL_FILE.GET_LINE(u_filehandle,v_buffer);
              EXCEPTION
              WHEN NO_DATA_FOUND
              THEN
              EXIT;
              END;
              n_bytes := UTL_TCP.WRITE_LINE(u_data_con,v_buffer);
              n_bytes_transmitted := n_bytes_transmitted + n_bytes;
         END LOOP;
         ELSIF UPPER(v_tsfr_mode) = 'GET'
         THEN
         LOOP
              BEGIN
              v_buffer := UTL_TCP.GET_LINE(u_data_con,TRUE);
              /** Sometimes the TCP/IP buffer sends null data **/
    /** we only want to receive the actual data **/
              IF v_buffer IS NOT NULL
              THEN
              UTL_FILE.PUT_LINE(u_filehandle,v_buffer);
              n_bytes := LENGTH(v_buffer);
              n_bytes_transmitted := n_bytes_transmitted + n_bytes;
              END IF;
              EXCEPTION
              WHEN UTL_TCP.END_OF_INPUT
              THEN
              EXIT;
              END;
         END LOOP;
         END IF;
         /** Flush the buffer on the data connection **/
         --UTL_TCP.FLUSH(u_data_con);
         d_trans_end := SYSDATE;
         /** Close the file **/
         UTL_FILE.FCLOSE(u_filehandle);
         /** Close the Data Connection **/
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
         /** Verify the transfer succeeded **/
         IF VALIDATE_REPLY(u_ctrl_con,TSFR_END_CODE,v_reply) = FALSE
         THEN
         RAISE ctrl_exception;
         END IF;
    EXCEPTION
    WHEN ctrl_exception
    THEN
         v_status := v_err_status;
         v_error_message := v_reply;
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN UTL_FILE.invalid_path
    THEN
         v_status      := v_err_status;
         v_error_message := 'Directory '||v_localpath||' is not available to UTL_FILE. Check the init.ora file for valid UTL_FILE directories.';
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN UTL_FILE.invalid_operation
    THEN
         v_status := v_err_status;
         IF UPPER(v_tsfr_mode) = 'PUT'
         THEN
         v_error_message := 'The file '||V_filename||' in the directory '||v_localpath||' could not be opened for reading.';
         ELSIF UPPER(v_tsfr_mode) = 'GET'
         THEN
         v_error_message := 'The file '||V_filename||' in the directory '||v_localpath||' could not be opened for writing.';
         END IF;     
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN UTL_FILE.read_error
    THEN
         v_status := v_err_status;
         v_error_message := 'The system encountered an error while trying to read '||v_filename||' in the directory '||v_localpath;
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN UTL_FILE.write_error
    THEN
         v_status := v_err_status;
         v_error_message := 'The system encountered an error while trying to write to '||v_filename||' in the directory '||v_localpath;
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN UTL_FILE.internal_error
    THEN
         v_status := v_err_status;
         v_error_message := 'The UTL_FILE package encountered an unexpected internal system error.';
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    WHEN OTHERS
    THEN
         v_status := v_err_status;
         v_error_message := SQLERRM;
         IF UTL_FILE.IS_OPEN(u_filehandle)
         THEN
         UTL_FILE.FCLOSE(u_filehandle);
         END IF;
         UTL_TCP.CLOSE_CONNECTION(u_data_con);
    END TRANSFER_ASCII;
    ** Handles connection to host and FTP of multiple files
    ** Files can be any combination of PUT and GET
    FUNCTION FTP_MULTIPLE(p_error_msg OUT VARCHAR2,
                   p_files IN OUT t_ftp_rec,
                   p_username IN VARCHAR2,
                   p_password IN VARCHAR2,
                   p_hostname IN VARCHAR2,
                   p_port IN PLS_INTEGER DEFAULT 21)
    RETURN BOOLEAN
    IS
         v_username           VARCHAR2(30)      := p_username;
         v_password           VARCHAR2(30)      := p_password;
         v_hostname           VARCHAR2(30)      := p_hostname;
         n_port               PLS_INTEGER      := p_port;
         u_ctrl_con          UTL_TCP.CONNECTION;
         n_byte_count          PLS_INTEGER;
         n_first_index          NUMBER;
         v_msg               VARCHAR2(250);
         v_reply               VARCHAR2(1000);
    v_pasv_host          VARCHAR2(20);
    n_pasv_port          NUMBER;
         invalid_transfer     EXCEPTION;
    BEGIN
         p_error_msg := 'FTP Successful'; --Assume the overall transfer will succeed
         /** Attempt to connect to the host machine **/
         u_ctrl_con := UTL_TCP.OPEN_CONNECTION(v_hostname,n_port);
         IF VALIDATE_REPLY(u_ctrl_con,CONNECT_CODE,v_reply) = FALSE
         THEN
         RAISE ctrl_exception;
         END IF;
         /** Send username **/
         n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'USER '||v_username);
         IF VALIDATE_REPLY(u_ctrl_con,USER_CODE,v_reply) = FALSE
         THEN
         RAISE ctrl_exception;
         END IF;
         /** Send password **/
         n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'PASS '||v_password);
         IF VALIDATE_REPLY(u_ctrl_con,LOGIN_CODE,v_reply) = FALSE
         THEN
         RAISE ctrl_exception;
         END IF;
         /** We should be logged in, time to transfer all files **/
         FOR i IN p_files.FIRST..p_files.LAST
    LOOP
         IF p_files.EXISTS(i)
         THEN
              BEGIN
              /** Change to the remotepath directory **/
              n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'CWD '||p_files(i).remotepath);
              IF VALIDATE_REPLY(u_ctrl_con,CWD_CODE,v_reply) = FALSE
              THEN
                   RAISE ctrl_exception;
              END IF;
              /** Switch to IMAGE mode **/
              n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'TYPE I');
              IF VALIDATE_REPLY(u_ctrl_con,TYPE_CODE,v_reply) = FALSE
              THEN
                   RAISE ctrl_exception;
              END IF;
              /** Get a Passive connection to use for data transfer **/
              n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'PASV');
              IF VALIDATE_REPLY(u_ctrl_con,PASV_CODE,v_reply) = FALSE
              THEN
                   RAISE ctrl_exception;
              END IF;
              CREATE_PASV(SUBSTR(v_reply,INSTR(v_reply,'(',1,1)+1,INSTR(v_reply,')',1,1)-INSTR(v_reply,'(',1,1)-1),v_pasv_host,n_pasv_port);
              /** Transfer Data **/
              IF UPPER(p_files(i).transfer_mode) = 'PUT'
              THEN
                   TRANSFER_ASCII(u_ctrl_con,
                        p_files(i).localpath,
                        p_files(i).filename,
                        v_pasv_host,
                        n_pasv_port,
                        p_files(i).transfer_mode,
                        p_files(i).status,
                        p_files(i).error_message,
                        p_files(i).bytes_transmitted,
                        p_files(i).trans_start,
         p_files(i).trans_end);
              ELSIF UPPER(p_files(i).transfer_mode) = 'GET'
              THEN
                   TRANSFER_ASCII(u_ctrl_con,
                        p_files(i).localpath,
                        p_files(i).filename,
                        v_pasv_host,
                        n_pasv_port,
                        p_files(i).transfer_mode,
                        p_files(i).status,
                        p_files(i).error_message,
                        p_files(i).bytes_transmitted,
                        p_files(i).trans_start,
         p_files(i).trans_end);
              ELSE
                   RAISE invalid_transfer; -- Raise an exception here
              END IF;
              EXCEPTION
              WHEN ctrl_exception
              THEN
              p_files(i).status := 'ERROR';
              p_files(i).error_message := v_reply;
              WHEN invalid_transfer
              THEN
              p_files(i).status := 'ERROR';
              p_files(i).error_message := 'Invalid transfer method. Use PUT or GET.';
              END;
         END IF;
         END LOOP;
         /** Send QUIT command **/
         n_byte_count := UTL_TCP.WRITE_LINE(u_ctrl_con,'QUIT');
         /** Don't need to validate QUIT, just close the connection **/
         UTL_TCP.CLOSE_CONNECTION(u_ctrl_con);
         RETURN TRUE;
    EXCEPTION
    WHEN ctrl_exception
    THEN
         p_error_msg := v_reply;
         UTL_TCP.CLOSE_ALL_CONNECTIONS;
         RETURN FALSE;
    WHEN OTHERS
    THEN
         p_error_msg := SQLERRM;
         UTL_TCP.CLOSE_ALL_CONNECTIONS;
         RETURN FALSE;
    END FTP_MULTIPLE;
    ** Convenience function for single-file PUT
    ** Formats file information for FTP_MULTIPLE function and calls it.
    FUNCTION PUT(p_localpath IN VARCHAR2,
              p_filename IN VARCHAR2,
              p_remotepath IN VARCHAR2,
              p_username IN VARCHAR2,
              p_password IN VARCHAR2,
              p_hostname IN VARCHAR2,
              v_status OUT VARCHAR2,
              v_error_message OUT VARCHAR2,
              n_bytes_transmitted OUT NUMBER,
              d_trans_start OUT DATE,
    d_trans_end OUT DATE,
              p_port     IN PLS_INTEGER DEFAULT 21,
              p_filetype IN VARCHAR2 := 'ASCII')
    RETURN BOOLEAN
    IS
         t_files      t_ftp_rec;
         v_username     VARCHAR2(30)      := p_username;
         v_password     VARCHAR2(50)      := p_password;
         v_hostname     VARCHAR2(100)      := p_hostname;
         n_port          PLS_INTEGER      := p_port;
    v_err_msg     VARCHAR2(255);
         b_ftp          BOOLEAN;
    BEGIN
         t_files(1).localpath          := p_localpath;
         t_files(1).filename           := p_filename;
         t_files(1).remotepath          := p_remotepath;
         t_files(1).filetype          := p_filetype;
         t_files(1).transfer_mode     := 'PUT';
         b_ftp := FTP_MULTIPLE(v_err_msg,
                   t_files,
                   v_username,
                   v_password,
                   v_hostname,
                   n_port);
         IF b_ftp = FALSE
         THEN
         v_status := 'ERROR';
         v_error_message := v_err_msg;
         RETURN FALSE;
         ELSIF b_ftp = TRUE
         THEN
         v_status                := t_files(1).status;
         v_error_message           := t_files(1).error_message;
         n_bytes_transmitted      := t_files(1).bytes_transmitted;
         d_trans_start           := t_files(1).trans_start;
         d_trans_end           := t_files(1).trans_end;
         RETURN TRUE;
         END IF;
    EXCEPTION
    WHEN OTHERS
    THEN
         v_status      := 'ERROR';
         v_error_message := SQLERRM;
         RETURN FALSE;
         --DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END PUT;
    ** Convenience function for single-file GET
    ** Formats file information for FTP_MULTIPLE function and calls it.
    FUNCTION GET(p_localpath IN VARCHAR2,
              p_filename IN VARCHAR2,
              p_remotepath IN VARCHAR2,
              p_username IN VARCHAR2,
              p_password IN VARCHAR2,
              p_hostname IN VARCHAR2,
              v_status OUT VARCHAR2,
              v_error_message OUT VARCHAR2,
              n_bytes_transmitted OUT NUMBER,
              d_trans_start OUT DATE,
    d_trans_end OUT DATE,
              p_port     IN PLS_INTEGER DEFAULT 21,
              p_filetype IN VARCHAR2 := 'ASCII')
    RETURN BOOLEAN
    IS
         t_files      t_ftp_rec;
         v_username     VARCHAR2(30)      := p_username;
         v_password     VARCHAR2(50)      := p_password;
         v_hostname     VARCHAR2(100)      := p_hostname;
         n_port          PLS_INTEGER      := p_port;
    v_err_msg     VARCHAR2(255);
         b_ftp          BOOLEAN;
    BEGIN
         t_files(1).localpath          := p_localpath;
         t_files(1).filename           := p_filename;
         t_files(1).remotepath          := p_remotepath;
         t_files(1).filetype          := p_filetype;
         t_files(1).transfer_mode     := 'GET';
         b_ftp := FTP_MULTIPLE(v_err_msg,
                   t_files,
                   v_username,
                   v_password,
                   v_hostname,
                   n_port);
         IF b_ftp = FALSE
         THEN
         v_status := 'ERROR';
         v_error_message := v_err_msg;
         RETURN FALSE;
         ELSIF b_ftp = TRUE
         THEN
         v_status           := t_files(1).status;
         v_error_message      := t_files(1).error_message;
         n_bytes_transmitted := t_files(1).bytes_transmitted;
         d_trans_start      := t_files(1).trans_start;
         d_trans_end      := t_files(1).trans_end;
         RETURN TRUE;
         END IF;
    EXCEPTION
    WHEN OTHERS
    THEN
         v_status      := 'ERROR';
         v_error_message := SQLERRM;
         RETURN FALSE;
         --DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END GET;
    END BRNC_FTP_PKG;
    /

  • ORA-00604 & ORA-30512 CANNOT MODIFY TABLE MORE THAN ONCE IN A TRANSACTION

    We have a requirement where two tables should be in sync at any given point
    in time with respect to the structure of the tables.
    Any change on table/column via ALTER (MODIFY, ADD, RENAME COLUMN, DROP
    COLUMN) on the parent table should be replicated to the replica table.
    I created a DDL_TRIGGER on the schema and the desired result is achieved but
    for the following one scenario for which its failing.
    The issue is, if we try to reduce the width of the column (via ALTER ..
    MODIFY) it fails with the following error
    ORA-00604: error occurred at recursive SQL level 1
    ORA-30512: cannot modify DEVTESTF_OIM.REPLICA_ABC more than once in a
    transaction
    Please follow the steps to reproduce the issue (the issue is across the DB
    version checked on 10.2, 11.1 and 11.2 DB version)
    -- Step1 Create Parent Table
    CREATE TABLE abc (col1 VARCHAR2(10))
    -- Step2 Create Replica Table
    CREATE TABLE replica_abc (col1 VARCHAR2(10))
    -- Step3 Create DDL Trigger
    CREATE OR REPLACE TRIGGER ddl_trigger
    AFTER ALTER ON SCHEMA
    DECLARE
    operation VARCHAR2(30);
    object_name VARCHAR2(30);
    l_sqltext VARCHAR2(100);
    i PLS_INTEGER;
    l_count NUMBER:=0;
    sql_text dbms_standard.ora_name_list_t;
    BEGIN
    i := dbms_standard.sql_txt(sql_text);
    SELECT ora_sysevent, ora_dict_obj_name, UPPER(sql_text(i))
    INTO operation, object_name, l_sqltext
    FROM dual;
    IF ora_dict_obj_name = 'ABC' THEN
    l_count := INSTR(l_sqltext,'ADD CONSTRAINT',1,1);
    l_count := l_count + INSTR(l_sqltext,'DISABLE',1,1);
    l_count := l_count + INSTR(l_sqltext,'DROP CONSTRAINT',1,1);
    l_count := l_count + INSTR(l_sqltext,'PRIMARY KEY',1,1);
    l_count := l_count + INSTR(l_sqltext,'ADD CHECK',1,1);
    IF (l_count = 0) THEN
    l_count := INSTR(l_sqltext,'ADD',1,1);
    l_count := l_count + INSTR(l_sqltext,'MODIFY',1,1);
    l_count := l_count + INSTR(l_sqltext,'DROP COLUMN',1,1);
    l_count := l_count + INSTR(l_sqltext,'RENAME
    COLUMN',1,1);
    IF (l_count >0) THEN
    l_sqltext := REPLACE(l_sqltext,'TABLE ABC','TABLE REPLICA_ABC');
    execute immediate l_sqltext;
    END IF;
    END IF;
    END IF;
    EXCEPTION
    WHEN OTHERS THEN
    RAISE ;
    END;
    -- Step 4 Issue the following ALTER command on the Parent table 'ABC'
    ALTER TABLE ABC MODIFY COL1 VARCHAR2(9);
    will show the following
    ERROR at line 1:
    ORA-00604: error occurred at recursive SQL level 1
    ORA-30512: cannot modify DEVTESTF_OIM.REPLICA_ABC more than once in a
    transaction
    ORA-06512: at line 34
    whereas the following commands works fine
    ALTER TABLE ABC MODIFY COL1 VARCHAR2(11);
    and also the rest of the operations
    ALTER TABLE ABC ADD COL2 VARCHAR2(20);
    ALTER TABLE ABC RENAME COLUMN COL2 TO COL3;
    ALTER TABLE ABC DROP COLUMN COL3;
    The issue is while reducing the size of VARCHAR2 columns, while the rest of
    option works fine.
    Any suggestion or workaround please.

    It looks like a bug to me. The failing statement from the SQL trace is
    PARSE ERROR #12:len=77 dep=3 uid=0 oct=3 lid=0 tim=1263332549608656 err=30512
    select /*+ first_rows */ 1 from "TIM"."REPLICA_ABC" where LENGTHB("COL1") > 9and exception cannot explain it.

  • Need help in executing report in OIM 10g

    Hi,
    I am getting error while executing a stored procedure for a report. The error is :
    ERROR,10 May 2012 00:25:07,649,[XELLERATE.WEBAPP],Class/Method: ReportAction/displayTabularReport encounter some problems: {1}
    Thor.API.Exceptions.tcColumnNotFoundException
    at Thor.API.tcMetaDataSet.getColumnType(Unknown Source)
    at com.thortech.xl.webclient.util.ReportUtilities.populateTableDataForTabularDisplay(Unknown Source)
    at com.thortech.xl.webclient.util.ReportUtilities.displayReportWithTabularLayout(Unknown Source)
    at com.thortech.xl.webclient.util.ReportUtilities.displayReportWithLayout(Unknown Source)
    at com.thortech.xl.webclient.actions.ReportAction.displayTabularReport(Unknown Source)
    at com.thortech.xl.webclient.actions.ReportAction.displayReport(Unknown Source)
    at com.thortech.xl.webclient.actions.ReportAction.handleInputParameters(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    for 2 days I am trying to solve this issue by trying different permutation and conbination but its not working. The table takes values from only two tables. Also I tried removing the othertable values and fetch value only from one table but still I am getting above error.
    Please help if anybody knows the solution for this.
    Thanks,
    Kalpana.

    I created my own report by copying from existing stored procedure. I just changed the select, from & where clause. I am not using any java program. Just changed the stored procedure, created the xml file, saved the parameter mappings in properties file, bounced the server but when I run the report I get this error.
    This is the xml file:
    <Report layout="tabular">
    <StoredProcedure>
    <InputParameters>
    <InputParameter name="struserlogin_in" order="1" fieldType="TextField" fieldLabel="report.contractorextension.label.reportDateRange" required="true" />
    </InputParameters>
    </StoredProcedure>
    <ReturnColumns>
    <ReturnColumn name="Contractor_Id" label="report.contractorextension.label.Contractor_Id" position="Table" order ="1"/>
    <ReturnColumn name="Contractor_Name" label="report.contractorextension.label.Contractor_Name" position="Table" order ="2"/>
    <ReturnColumn name="Contractor_NTLogon" label="report.contractorextension.label.Contractor_NTLogon" position="Table" order ="3"/>
    <ReturnColumn name="USR_STATUS" label="report.contractorextension.label.USR_STATUS" position="Table" order ="4"/>
    <ReturnColumn name="USR_END_DATE" label="report.contractorextension.label.USR_END_DATE" position="Table" order ="5"/>
    <ReturnColumn name="Supervisor_Name" label="report.contractorextension.label.Supervisor_Name" position="Table" order ="6"/>
    <ReturnColumn name="Supervisor_NTLogon" label="report.contractorextension.label.Supervisor_NTLogon" position="Table" order ="7"/>
    <ReturnColumn name="Supervsior_EmailId" label="report.contractorextension.label.Supervsior_EmailId" position="Table" order ="8"/>
    <ReturnColumn name="Notification_Send_Date" label="report.contractorextension.label.Notification_Send_Date" position="Table" order ="9"/>
    <ReturnColumn name="Extension_Date" label="report.contractorextension.label.Extension_Date" position="Table" order ="10"/>
    </ReturnColumns>
    </Report>
    this is the stored procedure:
    create or replace
    PROCEDURE "XL_SP_CONTRACTOREXTENSION" (
    csrresultset_inout IN OUT sys_refcursor,
    intuserkey_in IN NUMBER,
    strsortcolumn_in IN VARCHAR2,
    strsortorder_in IN VARCHAR2,
    intstartrow_in IN NUMBER,
    intpagesize_in IN NUMBER,
    intdocount_in IN NUMBER,
    inttotalrows_out OUT NUMBER,
    strfiltercolumnlist_in IN VARCHAR2,
    strfiltercolumnvaluelist_in IN VARCHAR2,
    strudfcolumnlist_in IN VARCHAR2,
    strudfcolumnvaluelist_in IN VARCHAR2,
    struserlogin_in IN VARCHAR2
    AS
    BEGIN
    Declare
    whereclause VARCHAR2(8000);
    select_stmt VARCHAR2(8000);
    strColumnList VARCHAR2(4000);
    strFromClause VARCHAR2(4000);
    strWhereClause VARCHAR2(4000);
    strOrderByClause VARCHAR2(2000);
    intSortDirection_in PLS_INTEGER;
    userkey NUMBER(30);
    str_row EXCEPTION;
    do_cnt EXCEPTION;
    no_logged_in_user EXCEPTION;
    property_not_found EXCEPTION;
    pragma exception_init(Str_row,-20001);
    pragma exception_init(Do_cnt,-20002);
    pragma exception_init(no_logged_in_user,-20003);
    BEGIN
    -- Throw exception if the start row or page size is either NULL or have
    -- values less than or equal to zero
    IF (intstartrow_in <= 0 OR intpagesize_in <= 0 OR intstartrow_in IS NULL
    OR intpagesize_in IS NULL) THEN
    RAISE str_row;
    END IF;
    -- Throw exception if the intdocount_in parameter is NULL or has a value
    -- other than 0 and 1
    IF intdocount_in NOT IN (0, 1, 2) OR intdocount_in IS NULL THEN
    RAISE do_cnt;
    END IF;
    -- Throw exception if the intuserkey_in (logged in user) parameter is NULL
    IF intuserkey_in IS NULL or intuserkey_in <= 0 THEN
    RAISE no_logged_in_user;
    END IF;
    -- Now, we start accumulating the whereclause based on the input
    -- parameters, performing error checking along the way.
    IF struserlogin_in IS NOT NULL THEN
    Whereclause :=
    whereclause || ' extn.udf_extn_ntlogon IN ( ''' || struserlogin_in || ''')' ;
    -- Perform the count query and store the result in inttotalrows_out
    -- inttotalrows_out := 0;
    IF intdocount_in IN (1,2)
    THEN
    EXECUTE IMMEDIATE ' SELECT count(*)'
    || ' FROM '
    || ' usr usr,usr usr2 '
    || ' where usr.USR_MANAGER_KEY = usr2.USR_KEY and'
    || ' extn.usr_key= usr.usr_key and '
    || whereclause INTO inttotalrows_out;
    -- UI needs the SP to return result set always. The following is returned
    -- when the indocount is 2 which does not return any result set but count
    IF intdocount_in = 2 THEN
    select_stmt := 'SELECT ''dummy'' FROM dual';
    OPEN csrresultset_inout FOR select_stmt;
    END IF;
    END IF;
    -- If intdocount_in is 2, UI just wants to get the totalrows to give
    -- the warning to users if the result set exceeds the limit set by
    -- UI. When ntdocount_in is 2, the following block won't be executed.
    -- This is the main query for this stored procedure
    If Intdocount_In In (0,1) Then
    -- The value of attestation field is NA in case of GTC resource names.
    -- If the GTC resource is selected, then "NA" will be displayed in the role name column
    Strcolumnlist :='usr.USR_LOGIN AS Contractor_Id, '
    --|| 'usr.USR_FIRST_NAME || '' '' || usr.usr_middle_name || '' '' || usr.USR_LAST_NAME AS "Contractor_NTLogon", '
    || 'usr.USR_FIRST_NAME AS Contractor_Name, '
    || 'usr.USR_UDF_NTLOGON AS Contractor_NTLogon,'
    || 'usr.USR_STATUS AS USR_STATUS, '
    || 'usr.USR_END_DATE AS USR_END_DATE, '
    --|| 'usr2.usr_first_name || '' '' || usr2.usr_middle_name || '' '' || usr2.usr_last_name AS "Supervisor_Name", '
    ||'usr2.usr_first_name AS Supervisor_Name, '
    || 'usr2.USR_UDF_NTLOGON AS Supervisor_NTLogon, '
    || 'usr2.USR_EMAIL AS Supervsior_EmailId'
    || 'extn.UDF_EXTN_CREATED AS Notification_Send_Date, '
    || 'extn.UDF_EXTN_EXTENDED AS Extension_Date';
    strFromClause :=' ud_co_extn_q extn, usr usr,usr usr2';
    strWhereClause := ' usr.USR_MANAGER_KEY = usr2.USR_KEY and '
    ||' extn.usr_key= usr.usr_key and '
    || whereclause;
    IF strsortcolumn_in IS NULL THEN
    strOrderByClause := 'extn.UDF_EXTN_EXTENDED';
    ELSE
    strOrderByClause := strsortcolumn_in;
    END IF;
    IF strsortorder_in = 'DESC' THEN
    intSortDirection_in := 0;
    ELSE
    intSortDirection_in := 1;
    END IF;
    XL_SPG_GetPagingSql(strColumnList,
    strFromClause,
    strWhereClause,
    strOrderByClause,
    intSortDirection_in,
    intStartRow_in,
    intPageSize_in,
    select_stmt);
    OPEN csrresultset_inout FOR select_stmt;
    END IF;
    END IF;
    -- Exception Handling
    EXCEPTION
    WHEN Str_row THEN
    RAISE_APPLICATION_ERROR(sqlcode,
    'Start Row/Page Size cannot be NULL OR less than or equal to zero ');
    WHEN Do_cnt THEN
    RAISE_APPLICATION_ERROR(sqlcode,
    'Do Count must be 0, 1 or 2. ');
    WHEN no_logged_in_user THEN
    RAISE_APPLICATION_ERROR(sqlcode,
    'Logged-in User Key cannot be NULL OR less than or equal to zero ');
    END;
    END XL_SP_CONTRACTOREXTENSION;

  • Not able to copy all the record from the table?

    Hi All,
    I have a table Table_1 with 5 crores of data. I have created the same table structure Table_2 like Table_1 and trying to insert the entire data from Table_1 to Table_2 by use of the below code:
    CREATE OR REPLACE PROCEDURE insert_prc (limit_in IN PLS_INTEGER)
    IS
        cursor cur_insert
        IS
        SELECT  *
        FROM    Table_1;
        type tabtype_insert IS TABLE OF cur_insert%ROWTYPE INDEX BY PLS_INTEGER;
        v_tabtype_insert   tabtype_insert;
        v_limit_rows    NUMBER := 1000;
        v_start    PLS_INTEGER;
        v_end      PLS_INTEGER;
        v_update_count  NUMBER;
        v_bulk_errors   NUMBER;   
    begin
        DBMS_SESSION.free_unused_user_memory;
        show_pga_memory (limit_in || ' - BEFORE');
        v_start := DBMS_UTILITY.get_cpu_time;
        BEGIN
            open cur_insert;
            LOOP
                FETCH cur_insert BULK COLLECT INTO v_tabtype_insert LIMIT v_limit_rows;
                FORALL i IN 1..v_tabtype_insert.COUNT SAVE EXCEPTIONS
                INSERT INTO  Table_2
                VALUES v_tabtype_insert(i);
                EXIT WHEN v_tabtype_insert.COUNT < v_limit_rows;
                COMMIT;
            END LOOP;
            CLOSE cur_insert;
        EXCEPTION
        WHEN OTHERS
        THEN
            v_update_count := 0;
            v_bulk_errors := SQL%BULK_EXCEPTIONS.COUNT;
            dbms_output.put_line('Number of INSERT statements that failed : ' ||v_bulk_errors);
            dbms_output.put_line('*******************************************************************************************************************');
            /*FOR i IN 1..v_bulk_errors
            LOOP
                dbms_output.put_line('An Error ' || i || ' was occured '|| SQL%BULK_EXCEPTIONS(i).ERROR_INDEX ||
                                    ' during update of Actuator Model: '|| v_tabtype_mtl_items(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX) ||
                                    ' . Oracle error : '|| SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
            END LOOP;   */
            dbms_output.put_line('*******************************************************************************************************************');
        END; 
          v_end := DBMS_UTILITY.get_cpu_time;
          DBMS_OUTPUT.put_line (   'Elapsed CPU time for limit of '
                                || limit_in
                                || ' = '
                                || TO_CHAR (v_end - v_start)/100
          show_pga_memory (limit_in || ' - AFTER');
    end insert_prc;
    CREATE OR REPLACE PROCEDURE APPS.show_pga_memory (
       context_in   IN   VARCHAR2 DEFAULT NULL
    SELECT privileges required on:
       SYS.v_$session
       SYS.v_$sesstat
       SYS.v_$statname
    Here are the statements you should run:
    GRANT SELECT ON SYS.v_$session TO schema;
    GRANT SELECT ON SYS.v_$sesstat TO schema;
    GRANT SELECT ON SYS.v_$statname TO schema;
    IS
       l_memory   NUMBER;
    BEGIN
       SELECT st.VALUE
         INTO l_memory
         FROM SYS.v_$session se, SYS.v_$sesstat st, SYS.v_$statname nm
        WHERE se.audsid = USERENV ('SESSIONID')
          AND st.statistic# = nm.statistic#
          AND se.SID = st.SID
          AND nm.NAME = 'session pga memory';
       dbms_output.put_line(CASE
                                   WHEN context_in IS NULL
                                      THEN NULL
                                   ELSE context_in || ' - '
                                END
                             || 'PGA memory used in session = '
                             || TO_CHAR (l_memory)
    END show_pga_memory;
    /From the above procedure i am able to insert only some 5000000 data. Remaining 4 crores data is not inserted. But the program says it is completed sucessfully.
    Note: Table_2 is the partitioned table and Table_1 is non partitioned table.
    Can anyone please what is the problem on above code?
    Thanks

    user212310 wrote:
    -- Using BULK COLLECTS and FORALL's will consume more resources.Ya i will agree that. That's what i am using LIMIT clause passing value as 1000. It means PL/SQL will reuse the same 1000 elements in the collection each time the data is fetched and thus also reuse the same memory. Even if my table grows in size, the PGA consumption will remain stable.Limit or not, your process will consume more resources (and take longer) than the one i showed you. AND it's many many many more lines of code (harder to maintain, etc...).
    user212310 wrote:
    -- If you don't have a reason (aside from misguided understandings as to which is more performant) to use BULK COLLECTS and FORALL's then you should go with the direct INSERT INTO SELECT * method.The reason i am using BULK COLLECT is to reduce the execution time of the procedure.
    Please let me know if i misunderstood something.
    ThanksYes, you have.
    Please read this
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:760210800346068768

  • What is the "Progid" of Adobe Acrobat reader.

    hi,
    I am trying to work on OLE invoke the Acrobat Reader File through
    ole container, just as to invode and create object for word we are using create_obj('word.application') .
    So the 'word.application' is stored in progid of registroy file.
    So , i am looking for any file which will be used to invoke pdf file , through ole.
    For example :
    for word progid is 'word.application'
    what is for Adobe Acrobat reader

    Here's a piece of code I got from someone else a long time ago and modified to open a PDF:
    PROCEDURE OPEN_PDF(vFile IN VARCHAR2)
    IS
    vcServerApp varchar2(40);
    vcServerTag varchar2(600);
    vcCommand varchar2(2000);
    iArgPos pls_integer;
    dummy NUMBER;
    BEGIN
    -- 1 get the Server App for .PDF files
    vcServerApp := win_api_environment.read_registry('HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\.PDF','',true);
    -- 2 get the executable
    vcServerTag := 'HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\'||
    vcServerApp||'\SHELL\OPEN\COMMAND';
    vcCommand:= win_api_environment.read_registry(vcServerTag,'',true);
    -- 3 Sort out how to specify the Filename
    iArgPos:= instr(vcCommand,'%1');
    if iArgPos = 0 then --no substitution Var on the command line
    vcCommand := vcCommand||' '||vFile;
    else
    vcCommand := substr(vcCommand,1,(iArgPos-1))||
    vFile||substr(vcCommand,(iArgPos+2));
    end if;
    -- 4 Run using Winexec (or Host if preferred).
    win_api_shell.winexec(vcCommand);
    EXCEPTION
    when no_data_found then
    abortt('Acrobat Reader was not found! Please consult with your help desk to install it and try again.','N');
    END;

  • Error on "webutil_c_api.invoke_int"

    Hello,
    i'm testing a DLL that was used in Oracle Forms 6i using ORA_FFI.
    the function that i'm testing it on Oracle 10g is :
    Function LS100_Open (hwnd in out pls_integer,
    Hinst in out pls_integer,
    Type_com in char) return pls_integer
    The Code in Oracle 10g is :
    declare
    ret_val      pls_integer;
    hwnd          pls_integer;     
    handle          pls_integer;     
    typ_com          varchar2(1):= 'S';
    f_handle      webutil_c_api.FunctionHandle;
    args          webutil_c_api.ParameterList;
    param1          webutil_c_api.ParameterHandle;
    param2          webutil_c_api.ParameterHandle;
    param3          webutil_c_api.ParameterHandle;
    begin
    f_handle := webutil_c_api.register_function('Ls100.dll','LS100_Open');
    args := webutil_c_api.create_parameter_list;
    param1 := webutil_c_api.add_parameter(args,webutil_c_api.c_int,webutil_c_api.param_out,hwnd);
    param2 := webutil_c_api.add_parameter(args,webutil_c_api.c_int,webutil_c_api.param_out,handle);
    param3 := webutil_c_api.add_parameter(args,webutil_c_api.c_char,webutil_c_api.param_in,typ_com,1);
    ret_val     := webutil_c_api.invoke_int('Ls100.dll','LS100_Open',args);
    WEBUTIL_C_API.Destroy_Parameter_List(args);
    WEBUTIL_C_API.Deregister_Function(f_handle);
    end;
    when i execute this code the following error appears:
    "WUL-910 Invoking the function failed: java.lang.IllegalArgumentException: unrecognized argument type"
    Is there anything wrong in my code ???

    hi,
    the function in dll is:
    -- pll in 6i ---
    LS100_lhandle ORA_FFI.LIBHANDLETYPE;
    LS100_Open_fhandle ORA_FFI.FUNCHANDLETYPE;
    FUNCTION ff_LS100_Open (LS100_Open_fhandle ORA_FFI.FUNCHANDLETYPE,
    hWnd IN OUT PLS_INTEGER,
    Hinst IN OUT PLS_INTEGER,
    Type_com IN CHAR) RETURN PLS_INTEGER;
    PRAGMA interface (C, ff_LS100_Open, 11265);
    FUNCTION LS100_Open (hWnd IN OUT PLS_INTEGER, --not a pointer
    Hinst IN OUT PLS_INTEGER, -- not a pointer
    Type_com IN CHAR) -- not a pointer
    RETURN PLS_INTEGER IS
    BEGIN
    RETURN( FF_LS100_Open( LS100_Open_fhandle, hWnd, Hinst, Type_com));
    END; /* function LS100_Open() */
    and in the documentation of the function in the library is defined as :
    LS100_Open
    #include "LS100.h"
    Result API LS100_Open (HWND      hwnd,
    HANDLE      Hinst,
    CHAR      Type_com);
    Description
    Open a connection between client and LS service.
    Parameters
    Hwnd     
    Handle of the application windows which will receive the notification messages.
    Hinst     
    Hinstance of the application window
    Type_com     
    Execution mode of the command:
    SUSPENSIVE_MODE = Synchronous mode
    NOT_SUSPENSIVE_MODE = Asynchronous mode
    Return Value
    LS100_OKAY if successful
    LS100_TRY_TO_RESET if the peripheral is in error state otherwise standard reply code.
    I have already the howto_ffi.html file and i have already did the following:
    - configuring the Webutil 1.0.5 (production release)
    - adding the library "LS100" to the Webutil.cfg
    - copy the library "LS100" and paste it into webutil\lib
    I also tried the following:
    I did omit the register/deregister_function, the code become as following and the same error occured after the 3rd add_parameter :
    declare
    ret_val      pls_integer;
    hwnd          number;     
    handle          number;     
    typ_com          varchar2(1):= 'S';
    len_typ          pls_integer := 1;
    f_handle      webutil_c_api.FunctionHandle;
    args          webutil_c_api.ParameterList;
    param1          webutil_c_api.ParameterHandle;
    param2          webutil_c_api.ParameterHandle;
    param3          webutil_c_api.ParameterHandle;
    xx number;
    yy number;
    begin
    -- f_handle := webutil_c_api.register_function('Ls100.dll','LS100_Open');
    args     := webutil_c_api.create_parameter_list;
    message('1');
    param1      := webutil_c_api.add_parameter(args,webutil_c_api.c_int,webutil_c_api.param_out,hwnd);
    message('2');
    param2      := webutil_c_api.add_parameter(args,webutil_c_api.c_int,webutil_c_api.param_out,handle);
    message('3');
    param3      := webutil_c_api.add_parameter(args,webutil_c_api.c_char,webutil_c_api.param_in,typ_com,len_typ);
    Now the same error appears in this stage:
    " WUL-910 Invoking the function failed: java.lang.IllegalArgumentException: unrecognized argument type "
    and the running continue
    message('before invoke_int');
    -- the "invoke_int" runs without any errors
    ret_val     := webutil_c_api.invoke_int('Ls100.dll','LS100_Open',args);
    xx := webutil_c_api.get_parameter_number(args,param1);
    yy := webutil_c_api.get_parameter_number(args,param2);
    message('hwnd ='||xx); -- => 0
    message('handle ='||yy); -- => 0
    message('ret_val ='||ret_val); -- => <nothing>
    WEBUTIL_C_API.Destroy_Parameter_List(args);
    --WEBUTIL_C_API.Deregister_Function(f_handle);                                        
    end;
    Thanks

  • Missing keyword error

    Hi all,
    I am getting missing keyword error when trying to execute the below function,it doesn't give an error while compiling though.Tried to debug but to vain,can't understand what i am missing.
       FUNCTION reprint_file (p_format          VARCHAR2,
                              p_printer_number  VARCHAR2,
                              p_request_id      VARCHAR2,
                              p_order_no_from   VARCHAR2 DEFAULT NULL,
                     p_order_no_to     VARCHAR2 DEFAULT NULL,
                     p_order_date_from VARCHAR2 DEFAULT NULL,
                     p_order_date_to   VARCHAR2 DEFAULT NULL
       RETURN VARCHAR2 IS
          CURSOR c_format(p_format VARCHAR2) IS
             SELECT *
             FROM   rgl_lookup_data
             WHERE  format_name = p_format;
          TYPE c_ref IS REF CURSOR;
          c_rec              c_ref;
          l_info             VARCHAR2(32767);
          l_stmt             VARCHAR2(6000);
          l_order_by         VARCHAR2(200):='';
          l_exec_stmt        VARCHAR2(8000);
          l_fp               UTL_FILE.FILE_TYPE;
          l_filename         VARCHAR2(200);
          --p_dir_name         VARCHAR2(200) := '/usr/tmp';
          p_dir_name VARCHAR2(200) := '/d02/oracle/edi/in';
          l_order_by_clause  VARCHAR2(240);
          l_cursor           PLS_INTEGER;
          l_return           NUMBER;
       BEGIN
          UPDATE rgl_mcy_line_data
          SET    printer_info = p_printer_number
          WHERE  header_id = p_request_id;
          l_stmt := 'SELECT ''"''||printer_info||''"'''; -- ||''","''||printer_info ';
          FOR curr_format IN c_format(p_format)
          LOOP
             IF curr_format.quantity IS NOT NULL THEN
                l_stmt := l_stmt || ' ||'',''||DECODE(quantity, NULL, NULL,''"''||'||'quantity||''"'')';
             END IF;
             IF curr_format.field_25 IS NOT NULL THEN
                l_stmt := l_stmt || ' ||'',''||DECODE(field_25, NULL, NULL,''"''||'||'field_25||''"'')';
             END IF;
          END LOOP curr_format;
          l_exec_stmt := l_stmt
                      || ' FROM rgl_lookup_data '
                      || ' WHERE format_name = :format_b';
          l_filename := 'Reprint_'||'ASP'||'_'||p_request_id||'_'||TO_CHAR(SYSDATE, '_DDMMYYYY_hh24MISS')||'.csv';
          l_fp := UTL_FILE.FOPEN(p_dir_name, l_filename, 'w');
          OPEN c_rec FOR l_exec_stmt USING p_format;
          FETCH c_rec INTO l_info;
          CLOSE c_rec;
          write_line(l_fp, l_info);
          l_exec_stmt := l_stmt
                      || ' FROM  rgl_mcy_line_data '
                      || ' WHERE header_id = :header_id_b '
                      || ' AND   format = :format_b '
                      || ' AND   printer_info = :printer_number_b ';
          IF p_order_no_from IS NOT NULL AND p_order_no_to IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_number BETWEEN :order_no_from_b TO :order_no_from_to ';
          ELSIF p_order_no_from IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_number >= :order_no_from_b ';
          ELSIF p_order_no_to IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_number <= :order_no_from_to ';
          END IF;
          IF p_order_date_from IS NOT NULL AND p_order_date_to IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_date BETWEEN :order_date_from_b TO :order_date_from_to ';
          ELSIF p_order_date_from IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_date >= :order_date_from_b ';
          ELSIF p_order_date_to IS NOT NULL THEN
             l_exec_stmt := l_exec_stmt
                         || ' AND order_date <= :order_date_from_to ';
          END IF;
          --log_mesg(l_exec_stmt);
    dbms_output.put_line('Entered');
          l_cursor := DBMS_SQL.OPEN_CURSOR;
          DBMS_SQL.PARSE(l_cursor, l_exec_stmt, DBMS_SQL.NATIVE); --Error is showing at this line
          DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, l_info, 32767);
          DBMS_SQL.BIND_VARIABLE(l_cursor, 'header_id_b', p_request_id);
          DBMS_SQL.BIND_VARIABLE(l_cursor, 'format_b', p_format);
          DBMS_SQL.BIND_VARIABLE(l_cursor, 'printer_number_b', p_printer_number);
    dbms_output.put_line('Exit');
          --log_mesg('req:'||p_request_id);
          --log_mesg('for:'||p_format);
          --log_mesg('pno:'||p_printer_number);
          IF p_order_no_from IS NOT NULL THEN
             --log_mesg('onf:'||p_order_no_from);
             DBMS_SQL.BIND_VARIABLE(l_cursor, 'order_no_from_b', p_order_no_from);
          END IF;
          IF p_order_no_to IS NOT NULL THEN
             --log_mesg('ont:'||p_order_no_to);
             DBMS_SQL.BIND_VARIABLE(l_cursor, 'order_no_to_b', p_order_no_to);
          END IF;
          IF p_order_date_from IS NOT NULL THEN
             --log_mesg('odf:'||p_order_date_from);
             DBMS_SQL.BIND_VARIABLE(l_cursor, 'order_date_from_b', p_order_date_from);
          END IF;
          IF p_order_date_to IS NOT NULL THEN
             --log_mesg('odt:'||p_order_date_to);
             DBMS_SQL.BIND_VARIABLE(l_cursor, 'order_date_to_b', p_order_date_to);
          END IF;
          l_return := DBMS_SQL.EXECUTE(l_cursor);
          LOOP
          --log_mesg('inside the loop')
             EXIT WHEN DBMS_SQL.FETCH_ROWS(l_cursor) = 0; --curr_rec%NOTFOUND;
             DBMS_SQL.COLUMN_VALUE(l_cursor, 1, l_info);
             write_line(l_fp, l_info);
          END LOOP;
          DBMS_SQL.CLOSE_CURSOR(l_cursor);
          UTL_FILE.FCLOSE(l_fp);
          UPDATE rgl_header_data
          SET    last_print_date = SYSDATE,
                 reprint_count = NVL(reprint_count, 0) + 1
          WHERE  header_id = p_request_id;
          COMMIT;
          EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
          RETURN l_filename;
       END rePrint_File;
    Function Call
    DECLARE
    v_result VARCHAR2(1000);
    BEGIN
    v_result := REGAL_MCY_PRINT_PKG.reprint_file('Macys.lwl','hp4000','6473482927','1213049','1213049',NULL,NULL);
    END;
    DBMS Messages
    Entered
    An error was encountered - -905 -ERROR- ORA-00905: missing keyword
    Any suggestions,
    Thanks in advance!!

    i didn't find anything wrong with this
    DBMS Message before parsing
    SELECT '"'||printer_info||'"' ||','||DECODE(quantity, NULL, NULL,'"'||quantity||'"') ||','||DECODE(format, NULL, NULL,'"'||format||'"') ||','||DECODE(duplicates, NULL,NULL,'"'||duplicates||'"') ||','||DECODE(field_1, NULL, NULL,'"'||field_1||'"') ||','||DECODE(field_2, NULL, NULL,'"'||field_2||'"') ||','||DECODE(field_3, NULL, NULL,'"'||field_3||'"') ||','||DECODE(field_4, NULL, NULL,'"'||field_4||'"') ||','||DECODE(field_5, NULL, NULL,'"'||field_5||'"') ||','||DECODE(field_6, NULL, NULL,'"'||field_6||'"') ||','||DECODE(field_7, NULL, NULL,'"'||field_7||'"') ||','||DECODE(field_8, NULL, NULL,'"'||field_8||'"') ||','||DECODE(field_9, NULL, NULL,'"'||field_9||'"') ||','||DECODE(field_10, NULL, NULL,'"'||field_10||'"') ||','||DECODE(field_11, NULL, NULL,'"'||field_11||'"') ||','||DECODE(field_12, NULL, NULL,'"'||field_12||'"') ||','||DECODE(field_13, NULL, NULL,'"'||field_13||'"') ||','||DECODE(field_14, NULL, NULL,'"'||field_14||'"') ||','||DECODE(field_15, NULL, NULL,'"'||field_15||'"') ||','||DECODE(field_16, NULL, NULL,'"'||field_16||'"') ||','||DECODE(field_17, NULL, NULL,'"'||field_17||'"') ||','||DECODE(field_18, NULL, NULL,'"'||field_18||'"') ||','||DECODE(field_19, NULL, NULL,'"'||field_19||'"') ||','||DECODE(field_20, NULL, NULL,'"'||field_20||'"') ||','||DECODE(field_21, NULL, NULL,'"'||field_21||'"') ||','||DECODE(field_22, NULL, NULL,'"'||field_22||'"') ||','||DECODE(field_23, NULL, NULL,'"'||field_23||'"') ||','||DECODE(field_24, NULL, NULL,'"'||field_24||'"') ||','||DECODE(field_25, NULL, NULL,'"'||field_25||'"') FROM  rgl_mcy_line_data  WHERE header_id = :header_id_b  AND   format = :format_b  AND   printer_info = :printer_number_b  AND order_number BETWEEN :order_no_from_b TO :order_no_from_to

  • Need Help: UTL_FILE Reading and Writing to Text File

    Hello I am using version 11gR2 using the UTL_FILE function to read from a text file then write the lines where it begins with word 'foo' and end my writing to the text file where the line with the word 'ZEN' is found. Now, I have several lines that begin with 'foo' and 'ZEN' Which make for one full paragraph, and in this paragraph there's a line that begins with 'DE4.2'. Therefore,
    I need to write all paragraphs that include the line 'DE4.2' in their beginning and ending lines 'foo' and 'ZEN'
    FOR EXAMPLE:
    FOO/234E53LLID
    THIS IS MY SECOND LINE
    THIS IS MY THIRD LINE
    DE4.2 THIS IS MY FOURTH LINE
    THIS IS MY FIFTH LINE
    ZEN/DING3434343
    FOO/234E53LLID
    THIS IS MY SECOND LINE
    THIS IS MY THIRD LINE
    THIS IS MY FIFTH LINE
    ZEN/DING3434343
    I am only interested in writing the first paragraph tha includes line DE4.2 in one of ther lines Not the Second paragraph that does not include the 'DE4.2'
    Here's my code thus far:
    CREATE OR REPLACE PROCEDURE my_app2 IS
    infile utl_file.file_type;
    outfile utl_file.file_type;
    buffer VARCHAR2(30000);
    b_paragraph_started BOOLEAN := FALSE; -- flag to indicate that required paragraph is started
    BEGIN
    -- open a file to read
    infile := utl_file.fopen('TEST_DIR', 'mytst.txt', 'r');
    -- open a file to write
    outfile := utl_file.fopen('TEST_DIR', 'out.txt', 'w');
    -- check file is opened
    IF utl_file.is_open(infile)
    THEN
    -- loop lines in the file
    LOOP
    BEGIN
    utl_file.get_line(infile, buffer);
         --BEGINPOINT APPLICATION
    IF buffer LIKE 'foo%' THEN
              b_paragraph_started := TRUE;          
         END IF;
         --LOOK FOR GRADS APPS
              IF b_paragraph_started AND buffer LIKE '%DE4%' THEN
              utl_file.put_line(outfile,buffer, FALSE);
    END IF;
         --ENDPOINT APPLICATION      
              IF buffer LIKE 'ZEN%' THEN
         b_paragraph_started := FALSE;
              END IF;
    utl_file.fflush(outfile);
    EXCEPTION
    WHEN no_data_found THEN
    EXIT;
    END;
    END LOOP;
    END IF;
    utl_file.fclose(infile);
    utl_file.fclose(outfile);
    EXCEPTION
    WHEN OTHERS THEN
    raise_application_error(-20099, 'Unknown UTL_FILE Error');
    END my_app2;
    When I run this code I only get one line: DE4.2 I AM MISSING THE ENTIRE PARAGRAPH
    PLEASE ADVISE...

    Hi,
    Look at where you're calling utl_file.put_line. The only time you're writing anything is immediately after you find the the key word 'DE4', and then you're writing just that line.
    You need to store the entire paragraph, and when you reach the end of the paragraph, write the whole thing only if you found the key word, like this:
    CREATE OR REPLACE PROCEDURE my_app2 IS
        TYPE  line_collection  
        IS       TABLE OF VARCHAR2 (30000)
               INDEX BY BINARY_INTEGER;
        infile               utl_file.file_type;
        outfile                      utl_file.file_type;
        input_paragraph          line_collection;
        input_paragraph_cnt          PLS_INTEGER     := 0;          -- Number of lines stored in input_paragraph
        b_paragraph_started      BOOLEAN      := FALSE;     -- flag to indicate that required paragraph is started
        found_key_word          BOOLEAN          := FALSE;     -- Does this paragraph contain the magic word?
    BEGIN
        -- open a file to read
        infile := utl_file.fopen('TEST_DIR', 'mytst.txt', 'r');
        -- open a file to write
        outfile := utl_file.fopen('TEST_DIR', 'out.txt', 'w');
        -- check file is opened
        IF utl_file.is_open(infile)
        THEN
         -- loop lines in the file
         LOOP
             BEGIN
              input_paragraph_cnt := input_paragraph_cnt + 1;
                 utl_file.get_line (infile, input_paragraph (input_paragraph_cnt));
              --BEGINPOINT APPLICATION
              IF LOWER (input_paragraph (input_paragraph_cnt)) LIKE 'foo%' THEN
                  b_paragraph_started := TRUE;
              END IF;
              --LOOK FOR GRADS APPS
              IF b_paragraph_started
              THEN
                  IF  input_paragraph (input_paragraph_cnt) LIKE '%DE4%'
                  THEN
                   found_key_word := TRUE;
                  END IF;
                  --ENDPOINT APPLICATION
                  IF input_paragraph (input_paragraph_cnt) LIKE 'ZEN%' THEN
                      b_paragraph_started := FALSE;
                   IF  found_key_word
                   THEN
                       FOR j IN 1 .. input_paragraph_cnt
                       LOOP
                           utl_file.put_line (outfile, input_paragraph (j), FALSE);
                       END LOOP;
                   END IF;
                   found_key_word := FALSE;
                   input_paragraph_cnt := 0;
                  END IF;
              ELSE     -- paragraph is not started
                  input_paragraph_cnt := 0;
              END IF;
              EXCEPTION
                  WHEN no_data_found THEN
                   EXIT;
              END;
          END LOOP;
        END IF;
        utl_file.fclose (infile);
        utl_file.fclose (outfile);
    --EXCEPTION
    --    WHEN OTHERS THEN
    --        raise_application_error(-20099, 'Unknown UTL_FILE Error');
    END my_app2;
    SHOW ERRORSIf you don't have an EXCEPTION section, the default error handling will print an error message, spcifying exactly what the error was, and which line of your code caused the error. By using your own EXCEPTION section, you're hiding all that information. I admit, the error messages aren't always as informative as we'd like, but they're never less informative than "Unknown UTL_FILE Error'. Don't use your own EXCEPTION handling unless you can improve on the default.
    Remember that anything inside quotes is case-sensitive. If your file contains upper-case 'FOO', then it won't be "LIKE 'foo%' ".
    Edited by: Frank Kulash on Dec 7, 2011 1:35 PM
    You may have noticed that this site normally doesn't display multiple spaces in a row.
    Whenever you post formatted text (such as your code) on this site, type these 6 characters:
    \{code}
    (small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing.

  • Sending PDF as attachment using utl_smtp

    Hi all,
    I am encountering the following problem when i try to send the email using utl_smtp builtin,i receive the mail in my outlook,but not able to read the contents of the pdf file.
    Oracle Version :- Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
    source code:-
    CREATE OR REPLACE PROCEDURE "PROC_MAIL_ATTACH_PDFS" (
    p_cust_nb IN cstm.cstm_cust_nb%TYPE,
    from_name IN VARCHAR2,
    to_name IN VARCHAR2,
    subject IN VARCHAR2,
    MESSAGE IN VARCHAR2,
    p_binary_file IN VARCHAR2,
    p_seq_id IN NUMBER,
    p_ret_cd OUT NUMBER,
    p_ret_desc OUT VARCHAR2
    --ISO-8859-6
    IS
    v_smtp_server VARCHAR2 (100) := '172.20.204.17';
    --change this to your mail server
    v_smtp_server_port NUMBER := 25;
    v_directory_name VARCHAR2 (100);
    v_file_name VARCHAR2 (100);
    v_line VARCHAR2 (1000);
    crlf VARCHAR2 (2) := CHR (13)
    || CHR (10);
    mesg VARCHAR2 (32767);
    conn UTL_SMTP.connection;
    v_slash_pos NUMBER;
    v_file_handle UTL_FILE.file_type;
    invalid_path EXCEPTION;
    mesg_length_exceeded BOOLEAN := FALSE;
    l_msg VARCHAR2 (32000);
    l_tag_sep VARCHAR2 (1)
    := func_get_config_value ('TAGSEPRTR');
    l_ind VARCHAR2 (10);
    l_rec VARCHAR2 (4000);
    l_sep_rep VARCHAR2 (4000) := '17_ACCSTMT_NOV_2010';
    l_rem_rep VARCHAR2 (4000);
    l_rep VARCHAR2 (4000);
    l_mim_type VARCHAR2 (2000);
    boundary CONSTANT VARCHAR2 (256)
    := '-----DMW.Boundary.605592468';
    first_boundary CONSTANT VARCHAR2 (256) := '--' || boundary || crlf;
    last_boundary CONSTANT VARCHAR2 (256)
    := '--' || boundary || '--' || crlf;
    multipart_mime_type CONSTANT VARCHAR2 (256)
    := 'multipart/mixed; boundary="' || boundary || '"';
    mime_type VARCHAR2 (255) := 'text/html';
    l_offset NUMBER;
    l_ammount NUMBER;
    CURSOR cur_trnm
    IS
    SELECT trnm_email_enarr, trnm_email_anarr
    FROM trnm
    WHERE trnm_id = 16;
    l_enarr trnm.trnm_email_enarr%TYPE;
    l_anarr trnm.trnm_email_enarr%TYPE;
    l_message_body VARCHAR2 (32000);
    --// To check if all mails belongs to the customer already sent...
    CURSOR cur_pdfd
    IS
    SELECT COUNT (*)
    FROM pdfd
    WHERE pdfd_cust_nb = p_cust_nb
    AND pdfd_email_sts IS NULL
    --NEWLY ADDED ...
    AND NVL (pdfd_stmt_mode, '.') = 'E'
    AND TRUNC (pdfd_to_dt) = (SELECT MAX (TRUNC (pdfd_to_dt))
    FROM pdfd
    WHERE pdfd_cust_nb = p_cust_nb);
    l_cnt NUMBER := 0;
    PROCEDURE send_header (NAME IN VARCHAR2, header IN VARCHAR2)
    IS
    BEGIN
    UTL_SMTP.write_data (conn, NAME || ': ' || header || crlf);
    END;
    PROCEDURE write_raw (
    p_conn IN OUT NOCOPY UTL_SMTP.connection,
    p_message IN RAW
    IS
    BEGIN
    UTL_SMTP.write_raw_data (p_conn, p_message);
    END write_raw;
    PROCEDURE binary_attachment (
    p_conn IN OUT UTL_SMTP.connection,
    p_file_name IN VARCHAR2,
    p_mime_type IN VARCHAR2
    IS
    k_max_line_width CONSTANT PLS_INTEGER DEFAULT 54;
    v_amt BINARY_INTEGER := 672 * 3;
    /* ensures proper format; 2016 */
    v_bfile BFILE;
    v_file_len PLS_INTEGER;
    v_buf RAW (2100);
    v_buf1 RAW (2100);
    v_modulo PLS_INTEGER;
    v_pieces PLS_INTEGER;
    v_file_pos PLS_INTEGER := 1;
    v_data RAW (32767);
    v_data1 RAW (32767);
    v_chunks PLS_INTEGER;
    l_amt NUMBER := 32767;
    l_off NUMBER := 1;
    l_raw RAW (32767);
    l_raw1 RAW (32767);
    l_lob BLOB;
    l_lob_empt BLOB;
    req UTL_HTTP.req;
    resp UTL_HTTP.resp;
    resp_empt UTL_HTTP.resp;
    l_url VARCHAR2 (4000);
    l_rep_path VARCHAR2 (2000);
    l_report VARCHAR2 (100);
    l_seq_nb repq.repq_seq_nb%TYPE;
    l_parm repq.repq_parm_val%TYPE;
    l_repq repq%ROWTYPE;
    l_sts NUMBER;
    l_user VARCHAR2 (10);
    --L_MSG VARCHAR2(32000);
    l_seq_id NUMBER;
    usr_err EXCEPTION;
    --// 07-Jun-2009 - Basheer A.S. : Code added for sending A/c Statement and PFL statements in single e-mail ...
    CURSOR cur_pdfd
    IS
    SELECT
    --UTL_COMPRESS.LZ_UNCOMPRESS(PDFD_DB_FILE) PDFD_DB_FILE,
    pdfd_file_name
    FROM pdfd
    WHERE pdfd_cust_nb = p_cust_nb
    --AND PDFD_EMAIL_STS IS NULL
    --NEWLY ADDED ...
    --AND NVL(PDFD_STMT_MODE,'.') = 'E'
    AND pdfd_seq_nb = p_seq_id
    AND TRUNC (pdfd_to_dt) = (SELECT MAX (TRUNC (pdfd_to_dt))
    FROM pdfd
    WHERE pdfd_cust_nb = p_cust_nb);
    l_buffer_size INTEGER := 57;
    l_offset INTEGER := 1;
    l_raw RAW (57);
    l_file_nm pdfd.pdfd_file_name%TYPE;
    BEGIN
    --// 06-Jun-2009 - Basheer A.S. : Code added for sending A/c Statement and PFL statements in a single e-mail ...
    --// Initializing temporary CLOB data ...
    DBMS_LOB.createtemporary (l_lob, FALSE);
    --DBMS_LOB.createtemporary(L_LOB_EMPT, FALSE);
    --// Loop thro all the records for the given Customer Number...
    OPEN cur_pdfd;
    LOOP
    --FETCH CUR_PDFD INTO L_LOB, L_FILE_NM;
    FETCH cur_pdfd
    INTO --L_LOB_EMPT,
    l_file_nm;
    EXIT WHEN cur_pdfd%NOTFOUND;
    proc_audit_log ('T',
    'PROC_MAIL_ATTACH_PDFS, Customer No. '
    || p_cust_nb
    || ', File attachment: '
    || l_file_nm
    UTL_SMTP.write_data (conn, first_boundary);
    UTL_SMTP.write_data (conn,
    'Content-Transfer-Encoding: base64 '
    || UTL_TCP.crlf
    UTL_SMTP.write_data (conn,
    'Content-Type: ' || mime_type || UTL_TCP.crlf
    UTL_SMTP.write_data (conn,
    'Content-Disposition: ATTACHMENT; filename="'
    || p_file_name
    || '"'
    || UTL_TCP.crlf
    UTL_SMTP.write_data (conn, crlf);
    l_ind := '1.1';
    v_file_pos := 1;
    --// Attaching individual PDF files ...
    BEGIN
    v_modulo := 0;
    v_pieces := 0;
    v_amt := 2016;
    l_ind := '2.1';
    v_file_len := DBMS_LOB.getlength (l_lob);
    --v_file_len := dbms_lob.getlength(L_LOB_EMPT);
    v_modulo := MOD (v_file_len, v_amt);
    v_pieces := TRUNC (v_file_len / v_amt);
    IF (v_modulo <> 0)
    THEN
    v_pieces := v_pieces + 1;
    END IF;
    l_ind := '2.2';
    DBMS_LOB.READ (l_lob, v_amt, v_file_pos, v_buf);
    --dbms_lob.read(L_LOB_EMPT, v_amt, v_file_pos, v_buf);
    v_data := v_data1;
    v_chunks := 0;
    v_data := v_data1;
    FOR i IN 1 .. v_pieces
    LOOP
    v_file_pos := i * v_amt + 1;
    v_file_len := v_file_len - v_amt;
    v_data := UTL_RAW.CONCAT (v_data, v_buf);
    l_ind := '2.3';
    v_chunks := TRUNC (UTL_RAW.LENGTH (v_data) / k_max_line_width);
    IF (i <> v_pieces)
    THEN
    v_chunks := v_chunks - 1;
    END IF;
    l_ind := '2.4';
    write_raw (p_conn => p_conn,
    p_message => UTL_ENCODE.base64_encode (v_data)
    v_data := v_data1;
    IF (v_file_len < v_amt AND v_file_len > 0)
    THEN
    v_amt := v_file_len;
    END IF;
    l_ind := '2.5';
    DBMS_LOB.READ (l_lob, v_amt, v_file_pos, v_buf);
    --DBMS_LOB.READ(L_LOB_EMPT, v_amt, v_file_pos, v_buf);
    END LOOP;
    EXCEPTION
    WHEN OTHERS
    THEN
    proc_audit_log
    ('E',
    'PROC_MAIL_ATTACH_PDFS.binary_attachment.inside BLOB loop, :'
    || SQLERRM
    || ',ind:'
    || l_ind
    END;
    v_file_pos := 1;
    UTL_SMTP.write_data (conn, UTL_TCP.crlf);
    UTL_SMTP.write_data (conn, UTL_TCP.crlf);
    END LOOP;
    --// END multiple file attachments
    l_ind := '2.6';
    UTL_SMTP.write_data (p_conn, last_boundary || UTL_TCP.crlf);
    EXCEPTION
    WHEN OTHERS
    THEN
    proc_audit_log ('E',
    'PROC_MAIL_ATTACH_PDFS, when others:'
    || l_ind
    || ', '
    || SQLERRM
    END binary_attachment;
    BEGIN
    --// If no pending emails for the given Customer, then exit the process...
    OPEN cur_pdfd;
    FETCH cur_pdfd
    INTO l_cnt;
    CLOSE cur_pdfd;
    --// If still pending statements needs to be send...
    --IF L_CNT > 0 THEN
    IF l_cnt = 0
    THEN
    OPEN cur_trnm;
    FETCH cur_trnm
    INTO l_enarr, l_anarr;
    CLOSE cur_trnm;
    l_message_body :=
    '<html>'
    ||
    --'<meta http-equiv="Content-Type" content="text/html; charset=WINDOWS-1256(Arabic)">'||
    --'<meta http-equiv="Content-Type" content="text/html; charset=WINDOWS-1256">'||
    '<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-6">'
    || '<body>
    <TABLE BORDER="0" WIDTH=100% style="table-layout:fixed;">
    <TR>
    <TD WIDTH="50%" ALIGN="LEFT" style="word-wrap: break-word"><B>'
    || l_enarr
    || '</B></TD>'
    || '<TD WIDTH="50%" ALIGN="RIGHT" style="word-wrap: break-word"><B>'
    || l_anarr
    || '</B></TD></TR></TABLE>
    </body>
    </html>';
    proc_audit_log ('T', 'PROC_MAIL_ATTACH_PDFS, msg:' || l_msg);
    v_smtp_server := func_get_config_value ('MAILHOST');
    v_smtp_server_port := func_get_config_value ('MAILPORT');
    l_ind := '3.1';
    conn := UTL_SMTP.open_connection (v_smtp_server, v_smtp_server_port);
    --utl_smtp.helo( conn, v_smtp_server );
    --utl_smtp.mail( conn, '[email protected]' );
    UTL_SMTP.helo (conn, v_smtp_server);
    UTL_SMTP.mail (conn, from_name);
    UTL_SMTP.rcpt (conn, to_name);
    l_ind := '3.2';
    l_rec := func_eti_tagval (l_msg, 'EMAIL');
    proc_audit_log ('T', 'PROC_MAIL_ATTACH_PDFS, l_rec:' || l_rec);
    proc_audit_log ('T', 'l_sep_rep1' || l_sep_rep);
    UTL_SMTP.open_data (conn);
    send_header ('From', '<' || from_name || '>');
    send_header ('To', '<' || to_name || '>');
    --send_header('To',''||Func_Eti_Tagval(L_MSG, 'EMAIL')||'');
    send_header ('Date', TO_CHAR (SYSDATE, 'dd Mon yy hh24:mi:ss'));
    send_header ('Subject', subject);
    send_header ('Content-Type', multipart_mime_type);
    UTL_SMTP.write_data (conn, first_boundary);
    --utl_smtp.write_data(conn, 'Content-Type: '||mime_type||utl_tcp.crlf);
    --utl_smtp.write_data(conn, 'Content-Type: '||mime_type||'; charset=Windows-1256'||utl_tcp.crlf);
    UTL_SMTP.write_data (conn,
    'Content-Type: '
    || mime_type
    || '; charset=ISO-8859-6'
    || UTL_TCP.crlf
    --new...
    UTL_SMTP.write_data (conn, crlf);
    UTL_SMTP.write_raw_data (conn, UTL_RAW.cast_to_raw (l_message_body));
    UTL_SMTP.write_data (conn, crlf);
    UTL_SMTP.write_data (conn, crlf);
    proc_audit_log ('T', 'l_sep_rep2' || l_sep_rep);
    binary_attachment (p_conn => conn,
    p_file_name => l_sep_rep || '.pdf',
    p_mime_type => 'multipart/mixed'
    ); --||l_sep_rep||'.pdf');
    UTL_SMTP.write_data (conn, last_boundary || UTL_TCP.crlf);
    UTL_SMTP.close_data (conn);
    UTL_SMTP.quit (conn);
    END IF;
    p_ret_cd := 0;
    p_ret_desc := 'Mail sent successfully';
    EXCEPTION
    WHEN OTHERS
    THEN
    proc_audit_log ('E',
    'PROC_MAIL_ATTACH_PDFS, error:'
    || SQLERRM
    || 'ind:'
    || l_ind
    p_ret_cd := 1;
    END;
    Kindly help me to resolve this issue.
    Thanks & Regards
    Ariff

    pl ease check below link
    /people/thomas.jung3/blog/2004/09/08/sending-e-mail-from-abap--version-610-and-higher--bcs-interface

  • Exporting Data from Forms to Excel

    Hi,
    How can I export the data from Forms to Excel like which Export function in the Oracle Applications.
    Thank you,
    Voon

    Hello,
    By using dde package you can export the data from Form to Excel. Here is the sample code which i have used. you can write this code in the when_button_pressed trigger.
    declare
    appl_name varchar2(255);
    channel_id pls_integer;
    application_id pls_integer;
    x number;
    y number;
    V_TIME VARCHAR2(30);
    begin
    if :global.application_id is not null then
    message('Application already open');
    else
    appl_name := 'c:\program files\microsoft office\office\excel.exe';
    :global.application_id := dde.app_begin(appl_name,dde.app_mode_normal);
    end if;
    if :global.channel_id is not null then
    message('Communication channel already established.');
    elsif :global.application_id is null then
    message('Application must be launched first.');
    else
    :global.channel_id := dde.initiate('excel','book1');
    end if;
    DDE.POKE(:global.channel_id,'R1C1','Col1 Heading',DDE.CF_TEXT,1000);
    DDE.POKE(:global.channel_id,'R1C2','Col2 Heading',DDE.CF_TEXT,1000);
    DDE.POKE(:global.channel_id,'R1C3','Col3 Heading',DDE.CF_TEXT,1000);
    FIRST_RECORD;
    X := No of Records;
    for y in 2..x
    loop
    launch_excel is a program unit--
    launch_excel(y,:global.channel_id,:block.item1,:block.item2,::block.item3);
    next_record;
    end loop;
    FIRST_RECORD;
    EXCEPTION
    WHEN DDE.DDE_APP_FAILURE THEN
    MESSAGE('Could not launch application for DDE operations.');
    RAISE FORM_TRIGGER_FAILURE;
    WHEN DDE.DDE_INIT_FAILED THEN
    MESSAGE('Could not initialize DDE communication channel.');
    RAISE FORM_TRIGGER_FAILURE;
    WHEN DDE.DMLERR_NO_CONV_ESTABLISHED THEN
    MESSAGE('Could not establish DDE communication channel.');
    RAISE FORM_TRIGGER_FAILURE;
    WHEN OTHERS THEN
    MESSAGE('Error: '&#0124; &#0124;TO_CHAR(SQLCODE)&#0124; &#0124;' '&#0124; &#0124;SQLERRM);
    RAISE FORM_TRIGGER_FAILURE;
    END;
    LAUNCH_EXCEL
    PROCEDURE LAUNCH_EXCEL(
    y in number,
    channel_id pls_integer,
    param1 varchar2,
    param2 VARCHAR2,
    param3 varchar2) IS
    v_rowno varchar2(20) := 'R'&#0124; &#0124;y;
    BEGIN
    dde.poke(channel_id,v_rowno&#0124; &#0124;'C1',col1,dde.cf_text,2000);
    dde.poke(channel_id,v_rowno&#0124; &#0124;'C2',col2,dde.cf_text,2000);
    dde.poke(channel_id,v_rowno&#0124; &#0124;'C3',col3,dde.cf_text,2000);
    EXCEPTION
    when others then
    message('Error --'&#0124; &#0124;sqlcode&#0124; &#0124;sqlerrm);
    message('Error --'&#0124; &#0124;sqlcode&#0124; &#0124;sqlerrm);
    raise form_trigger_failure;
    END;
    null

  • Other database delete is not working on forall statement

    Dear all,
    My scenario is , i create a program, the program fetch the data from database x and i want to delete on the same x database but i am running this program at y database, so
    so i created a view
    create or replace view vw_ibs_pda_bills_x as
    SELECT *
            FROM ibs_pda_bills_x@testarch1my program
    Declare
          CURSOR c2 IS
          SELECT *
            FROM vw_ibs_pda_bills_x
           WHERE bill_month <= '31-dec-2008'; -- AND bpref_no = :cons;
           opr varchar2(10) := 'DELETE';
          TYPE tsch IS TABLE OF c2%ROWTYPE;
          vtsch      tsch;
          cnt        NUMBER := 0;
          stime      NUMBER;
          etime      NUMBER;
          DURATION   NUMBER;
          rcount     NUMBER;
          errorsd   PLS_INTEGER;
          ecode     NUMBER;
          val1   VARCHAR2 (100);
          val2   VARCHAR2 (100);
          val3   VARCHAR2 (100);
          val4   VARCHAR2 (100);
       BEGIN
          BEGIN
             stime := DBMS_UTILITY.get_time ();
             OPEN c2;
             LOOP
                FETCH c2
                BULK COLLECT INTO vtsch LIMIT 1000;
                IF vtsch.COUNT = 1000
                THEN
                   cnt := cnt + 1;
                END IF;
            If opr = 'INSERT' Then
                    FORALL i IN 1 .. vtsch.COUNT SAVE EXCEPTIONS
                          INSERT INTO dlul.ibs_pda_bills
                        VALUES vtsch (i);
            Else
                    FORALL i IN 1 .. vtsch.COUNT SAVE EXCEPTIONS
                        Delete from vw_ibs_pda_bills_x where bill_month = vtsch(i).bill_month;
            End if;
                EXIT WHEN c2%NOTFOUND;
             END LOOP;
             etime := DBMS_UTILITY.get_time ();
             DURATION := ((etime - stime) / 100) / 60;
             rcount :=
                 (cnt * 1000) + vtsch.COUNT - NVL (SQL%BULK_EXCEPTIONS.COUNT, 0);
         If opr = 'INSERT' Then
             INSERT INTO process_stage_log
                  VALUES (SYSDATE, 'IBS_PDA_BILLS', DURATION, rcount);
         Else
             INSERT INTO process_stage_log
                  VALUES (SYSDATE, 'IBS_PDA_BILLS-D', DURATION, rcount);
         End if;
             CLOSE c2;
             COMMIT;
          EXCEPTION
             WHEN OTHERS
             THEN
                errorsd := SQL%BULK_EXCEPTIONS.COUNT;
                IF errorsd > 0
                THEN
                   FOR j IN 1 .. errorsd
                   LOOP
                      ecode := SQL%BULK_EXCEPTIONS (j).ERROR_CODE;
                      val1 :=
                           vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).sch_code;
                      val2 :=
                           vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).bpref_no;
                      val3 :=
                         vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).bill_month;
                      val4 :=
                         vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).service_code;
                  If opr = 'INSERT' Then         
                      INSERT INTO process_error_log
                           VALUES (SYSDATE, ecode, 'IBS_PDA_BILLS', 'sch_code', val1,
                                   'bpref_no', val2, 'bill_month', val3, 'service_code', val4,'INSERT');
              Else
                      INSERT INTO process_error_log
                           VALUES (SYSDATE, ecode, 'IBS_PDA_BILLS', 'sch_code', val1,
                                   'bpref_no', val2, 'bill_month', val3, 'service_code', val4,'DELETE');
              End if;
                   END LOOP;
                END IF;
          END;
       END pda_insert;the program want to do the delet option for all delete is not working. The program executed successful but the operation delete is not happening
    how to solve this issue.
    please help me
    kanish

    No error encountered in my log table
    the new workaround you said, that is instead of for all , already i tried for i in 1.. to like
    instead of forall delete i tried the following way
    Declare
          CURSOR c2 IS
    SELECT *
            FROM ibs_pda_bills_x@testarch1
           WHERE bill_month <= '31-dec-2008'; -- AND bpref_no = :cons;
           opr varchar2(10) := 'DELETE';
          TYPE tsch IS TABLE OF c2%ROWTYPE;
          vtsch      tsch;
          cnt        NUMBER := 0;
          stime      NUMBER;
          etime      NUMBER;
          DURATION   NUMBER;
          rcount     NUMBER;
          errorsd   PLS_INTEGER;
          ecode     NUMBER;
          val1   VARCHAR2 (100);
          val2   VARCHAR2 (100);
          val3   VARCHAR2 (100);
          val4   VARCHAR2 (100);
       BEGIN
          BEGIN
             stime := DBMS_UTILITY.get_time ();
             OPEN c2;
             LOOP
                FETCH c2
                BULK COLLECT INTO vtsch LIMIT 1000;
                IF vtsch.COUNT = 1000
                THEN
                   cnt := cnt + 1;
                END IF;
            If opr = 'INSERT' Then
                    FORALL i IN 1 .. vtsch.COUNT SAVE EXCEPTIONS
                          INSERT INTO dlul.ibs_pda_bills
                        VALUES vtsch (i);
            Else
                   /* fORALL i IN 1 .. vtsch.COUNT SAVE EXCEPTIONS
                     Delete from vw_ibs_pda_bills_x where to_char(bill_month,'dd-mm-rrrr') = to_char(vtsch (i).bill_month,'dd-mm-rrrr');*/
                     for i in 1..vtsch.count loop
                       delete ibs_pda_bills_x@testarch1 where to_char(bill_month,'dd-mm-rrrr') = to_char(vtsch (i).bill_month,'dd-mm-rrrr');
                     end loop; 
            End if;
                EXIT WHEN c2%NOTFOUND;
             END LOOP;
             etime := DBMS_UTILITY.get_time ();
             DURATION := ((etime - stime) / 100) / 60;
             rcount :=
                 (cnt * 1000) + vtsch.COUNT - NVL (SQL%BULK_EXCEPTIONS.COUNT, 0);
         If opr = 'INSERT' Then
             INSERT INTO process_stage_log
                  VALUES (SYSDATE, 'IBS_PDA_BILLS', DURATION, rcount);
         Else
             INSERT INTO process_stage_log
                  VALUES (SYSDATE, 'IBS_PDA_BILLS-D', DURATION, rcount);
         End if;
             CLOSE c2;
             COMMIT;
          EXCEPTION
             WHEN OTHERS
             THEN
                errorsd := SQL%BULK_EXCEPTIONS.COUNT;
                IF errorsd > 0
                THEN
                   FOR j IN 1 .. errorsd
                   LOOP
                      ecode := SQL%BULK_EXCEPTIONS (j).ERROR_CODE;
                      val1 :=
                           vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).sch_code;
                      val2 :=
                           vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).bpref_no;
                      val3 :=
                         vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).bill_month;
                      val4 :=
                         vtsch (SQL%BULK_EXCEPTIONS (j).ERROR_INDEX).service_code;
                  If opr = 'INSERT' Then         
                      INSERT INTO process_error_log
                           VALUES (SYSDATE, ecode, 'IBS_PDA_BILLS', 'sch_code', val1,
                                   'bpref_no', val2, 'bill_month', val3, 'service_code', val4,'INSERT');
              Else
                      INSERT INTO process_error_log
                           VALUES (SYSDATE, ecode, 'IBS_PDA_BILLS', 'sch_code', val1,
                                   'bpref_no', val2, 'bill_month', val3, 'service_code', val4,'DELETE');
              End if;
                   END LOOP;
                END IF;
          END;
       END pda_insert;i am receiving the following error
    ORA-02055: distributed update operation failed; rollback required
    ORA-06531: Reference to uninitialized collection
    ORA-06512: at line 77
    ORA-06531: Reference to uninitialized collection
    kanish

  • How can I get the list of all canvas in the forms programatically?

    I want an exemple of how to do it. I really need it to put in a template.

    This is the code.
    You will see how to loop through every item of every blocks of the form:
    PROCEDURE Get_Canvas_Names IS
      lc$blockDeb     varchar2(60); -- start block
      lc$block          varchar2(60); -- current block name
      lc$item               varchar2(60); -- current item
      lc$Type               varchar2(20); -- item type
      lc$itemdeb     varchar2(60); -- first item
      lc$canvas          varchar2(60); -- current canvas name
      lc$tabcan          varchar2(60); -- current tab canvas name
      lc$Acanvas     varchar2(60):= ' '; -- old canvas name
      lc$Atabcan     varchar2(60):= ' '; -- old tab canvas name
      ln$NbRec          pls_integer := 0 ;  -- number of records (for know if the block is multi-records)
    BEGIN
      LC$BlockDeb := get_form_property( NAME_IN('System.Current_Form'), FIRST_BLOCK ) ;
      LC$Block := LC$BlockDeb ;
      Loop -- For each block of the form
      LN$NbRec   := get_block_property(LC$BLOCK, RECORDS_DISPLAYED) ;
      lc$itemdeb := get_block_property(LC$BLOCK, FIRST_ITEM) ;
      lc$item := LC$BLOCK || '.' || lc$itemdeb ;
      while lc$itemdeb is not null loop -- For each item
        -- visible item ? --
        IF GET_ITEM_PROPERTY(LC$Item , VISIBLE) = 'TRUE' Then
             -- Get the canvas and tab canvas name --
             lc$canvas := GET_ITEM_PROPERTY(LC$Item , ITEM_CANVAS ) ;
             lc$tabcan := GET_ITEM_PROPERTY(LC$Item , ITEM_TAB_PAGE ) ;
        End if ; -- GET_ITEM_PROPERTY(LC$Item , VISIBLE) = 'TRUE'   
        lc$itemdeb := get_item_property(lc$item, NEXT_NAVIGATION_ITEM );
        lc$item := LC$BLOCK || '.' || lc$itemdeb ;
      end loop ;
      LC$Block := get_block_property( LC$Block, NEXTBLOCK ) ; -- next block
      exit when LC$Block is null ;
      End loop ;
    END Get_Canvas_Names;all you have to do is to save each different canvas names in a pl/sql table.
    Francois

Maybe you are looking for

  • Error while running ejbc. Fatal error from EJB Compiler ---- Error while pr

    Hi! I was deploying a test application for a session bean with sun 1 studio 5 and I started getting this message while deploying. I had tested the bean previously and I had no problems. I found this in the sun app server 7 release notes, but I don't

  • PDFs are blank in Acrobat X

    I have Acrobat Pro X - when I go to open a PDF, it appears blank with no text. Images show up, and I can see that there is text in the document when i open through Preview, but when I ope in Acrobat, it's not there. I had unchecked "enhanced security

  • Unable to see correlation in receiver step of BPM.

    Hi, I am designing a BPM in XI. In a receiver step I need a correlation. I am able to select a correlation from the drop down of the field "Activate Correlations" but when it is activated, the correlation is not displayed. I am using SAP XI 7.4 and S

  • Actively changing number of elements in an array

    How do you use a control in the front panel to actively change the number of rows in an array which full of numeric controls? Is it possible to have this happen without the program to be running? Thanks for any help. Solved! Go to Solution.

  • Is there any function module to convert the date format

    Dear ABAPers, Is there any function module to convert the date format from dd.mm.yyyy to dd-mmm-yyyy.        I want to convert the date format from dd.mm.yyy to dd.mmm.yyy Eg.from 10.03.2008 to 10-mar-2009. Thanks & Regards, Ashok.