FTP SQL

I am learning SQL on a remote system. Part of my lesson requires me to create an SQL file on my PC with spool commands and execute it. How do I do that to a file at home?
I use the command interface.
Somone said FTP but its not working. I am only able to get to the to the ftp> prompt.
Thanks guys.

This is very helpful, Sidhu.
So what you are saying is I could create a text file at SQLplus SQL> and open it with the ED command?
If I could create a text file at SQL> I could work with that until I could do it at home on the 10 g Express I downloaded.
Thanks again Sidhu
<<david said everything....
otherwise if you want to create a SQL file from SQL prompt then you can do "ed file_name",it will open notepad (or whatever editor is defined, vi on Unix based systems) write whatever code you want, then save and close.
now you can run the same file as
SQL> @file_name
on the other hand to FTP some file from one machine to another...you need to have FTP enabled on the machine to which you are connecting..
go to command prompt,open FTP connection like
c:\>ftp <ip address>
enter username & password
then you can use put to send the file and get to recieve the file..
Sidhu >>

Similar Messages

  • Changing oracle file permission with ftp / sql

    Hi, i have a question:
    I've configure webdav to browse my /i folder.
    I can use as well filezilla, connecting with hostname / uname: system / pass / myoraclesystem pass.
    Is there a way to change file permission attributes with ftp?
    Thank you

    Hi,
    Check out ORDSYS.ORDImage type from Oracle Intermedia, and especially its "process" method.
    It possesses various commands to change image properties.
    HTH.

  • Best way for LV app to communicate with Database/Website?

    Hey all...I'm pretty experienced LabVIEW programmer but I'm in somewhat new territory here with communicating with a server/website.
    We are going to have an online SQL database that stores all data that we record for our application.  That database is going to have a web-based front end that will allow users to add/edit records.
    On the other end, we are going to have a LabVIEW application running on a PC that will allow its users to acquire/input data, and also add/edit records for the SQL database as well.  So basically a web-based client and a LV application client, which will most likely differ in functionality.
    There are going to be multiple PCs running LabVIEW client
    applications (let's assume upwards of 20 for now).  The idea would be
    that the user could:
    Query the SQL database for an existing entry, and then view/edit that entry or add records to it.
    Create an entirely new record. 
    I have played around with the database connectivity toolkit and was able to communicate with the SQL databases online, no problem.  But, I'm not sure if that is the best way to do this yet because....
    Here are our challenges/constraints/specifications:
    Well we need this to be as low bandwidth intensive as possible as each LV client will be using a GPRS(cell phone) data connection to the internet which is pay per use.  Here are my thoughts on this so far:
    Having local copies of often accessed records on each machine with incremental updates to the server to minimize bandwidth for queries.
    Positives/Negatives?
    Send data to the server in a tagged format (XML maybe?) and then have a server-side application that parses the data and updates it to the database.
    Postives/Negatives?
    When updates are made using the website front-end...we would like at a minimum to be able to notify the LV client that an update has been made (like a Push data/notifier service). 
    How to implement?
    POP3 e-mail for each LV client might be an option but is there something better?
    The data types that we are working with include all standard types (numeric, text, timestamps) and also includes images (jpg) and sound files (mp3) and potentially video in the future.
    Thanks and I'm looking for any and all feedback.  Let me know if the problem is still fuzzy...I will try to describe in better detail.
    -Aaron
    Aaron Fleishman
    Certified LabVIEW Associate Developer
    LabVIEW 2011

    MattBradley wrote:
    Next question: Can the clients (easily) talk to each other -- if they can make a single file for updating the server, that could help, too.
    In any case, my first thought would be to put the different priority data in different directories. Have another labview (or even a different software package) running in the background, looking for new data (more often in the high priority directories). When it sees something, copy it to the server. When the server confirms the file has arrived, delete the original one. On the server side, it would have to let the client know it received the file and then unzip it/translate it/whatever and insert it into the database.
    Sound good so far?
    -Matt
    Matt,
    Sounds good so far.  Interesting idea of putting it in different directories, although I'd like to minimize file I/O as much as possible, especially between different VIs.  I'm also intrigued by using .zip files to cut down on file size.
    No, the clients won't easily be able to talk to each other.  All messaging between clients will go through the server as well.
    I guess I'm really looking for how to practically implement this as well.  Like what VIs (protocol) should I be using to get the data to the server?  TCP/UDP/SMTP/FTP/SQL connection/etc...I have little experience making apps communicate with a website/webserver.
    -Aaron
    Aaron Fleishman
    Certified LabVIEW Associate Developer
    LabVIEW 2011

  • How to Deploy Oracle 10g Express to JBOSS

    I am trying to learn JBOSS 4.03, Oracle 10g Express, & myEclipse 4.1.1 for a class project and get the following error when trying to deploy oracle to JBOSS.
    --- Packages waiting for a deployer ---
    org.jboss.deployment.DeploymentInfo@67e105b1 { url=file:/C:/Program Files/jboss-4.0.3SP1/server/default/deploy/oracle-ds.xml }
    deployer: null
    status: null
    state: INIT_WAITING_DEPLOYER
    watch: file:/C:/Program Files/jboss-4.0.3SP1/server/default/deploy/oracle-ds.xml
    altDD: null
    lastDeployed: 1142921147203
    lastModified: 1142921147203
    mbeans:
    --- Incompletely deployed packages ---
    org.jboss.deployment.DeploymentInfo@67e105b1 { url=file:/C:/Program Files/jboss-4.0.3SP1/server/default/deploy/oracle-ds.xml }
    deployer: null
    status: null
    state: INIT_WAITING_DEPLOYER
    watch: file:/C:/Program Files/jboss-4.0.3SP1/server/default/deploy/oracle-ds.xml
    altDD: null
    lastDeployed: 1142921147203
    lastModified: 1142921147203
    mbeans:
    Does anyone know of a good online tutorial for this or has anyone solved this problem? All I did was copy the oracle-ds.xml file from oracle into C:\Program Files\jboss-4.0.3SP1\server\default\deploy

    hi,
    Do this...
    Get  Current Config....
    sqlplus system@xe
    SQL*Plus: Release 10.1.0.2.0 - Production on Mi Jan 25 11:44:33 2006
    Copyright (c) 1982, 2004, Oracle. All rights reserved.
    Enter password:
    Connected to:
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Beta
    SQL> select dbms_xdb.gethttpport as "HTTP-Port"
    , dbms_xdb.getftpport as "FTP-Port" from dual;
    HTTP-Port FTP-Port
    8080 0
    Change Port HTTP and FTP.
    SQL> begin
    2 dbms_xdb.sethttpport('80');
    3 dbms_xdb.setftpport('2100');
    4 end;
    5 /
    PL/SQL procedure successfully completed.
    SQL> select dbms_xdb.gethttpport as "HTTP-Port"
    , dbms_xdb.getftpport as "FTP-Port" from dual;
    HTTP-Port FTP-Port
    80 2100
    Disable HTTP and FTP
    SQL> begin
    2 dbms_xdb.sethttpport('0');
    3 dbms_xdb.setftpport('0');
    4 end;
    5 /
    PL/SQL procedure successfully completed.
    SQL> -- get current status
    SQL> select dbms_xdb.gethttpport as "HTTP-Port"
    , dbms_xdb.getftpport as "FTP-Port" from dual;
    HTTP-Port FTP-Port
    0 0
    Regards,
    Levi Pereira

  • "ORA-00902: invalid datatype" when trying to register local schema

    I'm trying to register a local schema which uses/includes a global schema(s). I validated the schemas using XMLSpy.
    Registering the global schema(s) was successful. Registering these global schemas was done under user "Generic". For local schemas, that use global schema, a new user is created, and the following script is executed.
    SQL> --
    SQL> -- Create user
    SQL> --
    SQL> create user &1 identified by &2
    2 temporary TABLESPACE temp
    3 default TABLESPACE users;
    old 1: create user &1 identified by &2
    new 1: create user Simple identified by Simple
    User created.
    Elapsed: 00:00:00.03
    SQL> --
    SQL> -- Grant privileges
    SQL> --
    SQL> grant create session to &1;
    old 1: grant create session to &1
    new 1: grant create session to Simple
    Grant succeeded.
    Elapsed: 00:00:00.01
    SQL> grant resource to &1;
    old 1: grant resource to &1
    new 1: grant resource to Simple
    Grant succeeded.
    Elapsed: 00:00:00.01
    SQL> -- Dunno if following is required for local schemas, but if I remove I can't FTP
    SQL> grant dba, xdbadmin to &1;
    old 1: grant dba, xdbadmin to &1
    new 1: grant dba, xdbadmin to Simple
    Grant succeeded.
    Elapsed: 00:00:00.02
    SQL>
    SQL> --
    SQL> -- Connect ;-)
    SQL> --
    SQL> connect &1/&2@SVF91;
    Connected.
    ===========================================================
    SQL> --
    SQL> -- Register the schema in Oracle
    SQL> --
    SQL> BEGIN
    2 DBMS_XMLSchema.registerSchema(
    3      schemaURL => '&1',
    4      schemaDoc => xdbURIType('&2').getClob(),
    5      local     => TRUE,
    6      genTypes => TRUE,
    7      genBean => FALSE,
    8      genTables => TRUE);
    9 END;
    10 /
    old 3: schemaURL     => '&1',
    new 3: schemaURL     => 'http://http://ehvl091a:8080/home/Simple/xsd/SimplePOI.xsd',
    old 4: schemaDoc     => xdbURIType('&2').getClob(),
    new 4: schemaDoc     => xdbURIType('/home/Simple/xsd/SimplePOI.xsd').getClob(),
    BEGIN
    ERROR at line 1:
    ORA-31084: error while creating table "SIMPLE"."SIMPLE_XPOI" for element
    "XPOIS"
    ORA-00902: invalid datatype
    ORA-06512: at "XDB.DBMS_XMLSCHEMA_INT", line 20
    ORA-06512: at "XDB.DBMS_XMLSCHEMA", line 31
    ORA-06512: at line 2
    The schema I use is:
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:POI="POI" xmlns:xdb="http://xmlns.oracle.com/xdb" targetNamespace="POI" elementFormDefault="qualified" attributeFormDefault="unqualified" xdb:storeVarrayAsTable="true">
         <xs:include schemaLocation="http://ehvl091a:8080/home/Generic/xsd/POI.xsd"/>
         <xs:element name="XPOIS" xdb:defaultTable="SIMPLE_XPOI">
              <xs:annotation>
                   <xs:documentation>A collection of XPOI</xs:documentation>
              </xs:annotation>
              <xs:complexType>
                   <xs:sequence>
                        <xs:element name="Simple" minOccurs="3" maxOccurs="unbounded" xdb:columnProps="NOT SUBSTITUTABLE">
                             <xs:complexType>
                                  <xs:complexContent>
                                       <xs:extension base="POI:POIType"/>
                                  </xs:complexContent>
                             </xs:complexType>
                        </xs:element>
                   </xs:sequence>
              </xs:complexType>
         </xs:element>
    </xs:schema>
    I'm new at this XML (Oracle) stuff, so i could really use some pointers on how to tackle this. Thanks in advance.

    The following example works for me...
    SQL> connect / as sysdba
    Connected.
    SQL> --
    SQL> drop user global cascade
      2  /
    User dropped.
    SQL> drop user local cascade
      2  /
    User dropped.
    SQL> create user global identified by global
      2  /
    User created.
    SQL> grant connect, resource, alter session, create view, xdbadmin to global
      2  /
    Grant succeeded.
    SQL> create user local identified by local
      2  /
    User created.
    SQL> grant connect, resource, alter session, create view to local
      2  /
    Grant succeeded.
    SQL> connect global/global
    Connected.
    SQL> --
    SQL> var schemaURL varchar2(256)
    SQL> var schemaPath varchar2(256)
    SQL> --
    SQL> begin
      2    :schemaURL := 'poTypes.xsd';
      3    :schemaPath := '/public/poTypes.xsd';
      4  end;
      5  /
    PL/SQL procedure successfully completed.
    SQL> declare
      2    res boolean;
      3    xmlSchema xmlType := xmlType(
      4  '<!-- edited with XML Spy v4.0 U (http://www.xmlspy.com) by Mark (Drake) -->
      5  <xs:schema xmlns="http://xmlns.oralce.com/demo/xdb/purchaseOrderTypes" targetNamespace="http://xmlns.oralce.com/demo/xdb/purchaseOrderT
    ypes" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdb="http://xmlns.oracle.com/xdb" version="1.0" xdb:storeVarrayAsTable="true">
      6     <xs:complexType name="LineItemsType" xdb:SQLType="LINEITEMS_T">
      7             <xs:sequence>
      8                     <xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded" xdb:SQLName="LINEITEM" xdb:SQLCollType="LINEIT
    EM_V"/>
      9             </xs:sequence>
    10     </xs:complexType>
    11     <xs:complexType name="LineItemType" xdb:SQLType="LINEITEM_T">
    12             <xs:sequence>
    13                     <xs:element name="Description" type="DescriptionType" xdb:SQLName="DESCRIPTION"/>
    14                     <xs:element name="Part" type="PartType" xdb:SQLName="PART"/>
    15             </xs:sequence>
    16             <xs:attribute name="ItemNumber" type="xs:integer" xdb:SQLName="ITEMNUMBER" xdb:SQLType="NUMBER"/>
    17     </xs:complexType>
    18     <xs:complexType name="PartType" xdb:SQLType="PART_T">
    19             <xs:attribute name="Id" xdb:SQLName="PART_NUMBER" xdb:SQLType="VARCHAR2">
    20                     <xs:simpleType>
    21                             <xs:restriction base="xs:string">
    22                                     <xs:minLength value="10"/>
    23                                     <xs:maxLength value="14"/>
    24                             </xs:restriction>
    25                     </xs:simpleType>
    26             </xs:attribute>
    27             <xs:attribute name="Quantity" type="moneyType" xdb:SQLName="QUANTITY"/>
    28             <xs:attribute name="UnitPrice" type="quantityType" xdb:SQLName="UNITPRICE"/>
    29     </xs:complexType>
    30     <xs:simpleType name="ReferenceType">
    31             <xs:restriction base="xs:string">
    32                     <xs:minLength value="18"/>
    33                     <xs:maxLength value="30"/>
    34             </xs:restriction>
    35     </xs:simpleType>
    36     <xs:complexType name="ActionsType" xdb:SQLType="ACTIONS_T">
    37             <xs:sequence>
    38                     <xs:element name="Action" maxOccurs="4" xdb:SQLName="ACTION" xdb:SQLCollType="ACTION_V">
    39                             <xs:complexType xdb:SQLType="ACTION_T">
    40                                     <xs:sequence>
    41                                             <xs:element name="User" type="UserType" xdb:SQLName="ACTIONED_BY"/>
    42                                             <xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_ACTIONED"/>
    43                                     </xs:sequence>
    44                             </xs:complexType>
    45                     </xs:element>
    46             </xs:sequence>
    47     </xs:complexType>
    48     <xs:complexType name="RejectionType" xdb:SQLType="REJECTION_T">
    49             <xs:all>
    50                     <xs:element name="User" type="UserType" minOccurs="0" xdb:SQLName="REJECTED_BY"/>
    51                     <xs:element name="Date" type="DateType" minOccurs="0" xdb:SQLName="DATE_REJECTED"/>
    52                     <xs:element name="Comments" type="CommentsType" minOccurs="0" xdb:SQLName="REASON_REJECTED"/>
    53             </xs:all>
    54     </xs:complexType>
    55     <xs:complexType name="ShippingInstructionsType" xdb:SQLType="SHIPPING_INSTRUCTIONS_T">
    56             <xs:sequence>
    57                     <xs:element name="name" type="NameType" minOccurs="0" xdb:SQLName="SHIP_TO_NAME"/>
    58                     <xs:element name="address" type="AddressType" minOccurs="0" xdb:SQLName="SHIP_TO_ADDRESS"/>
    59                     <xs:element name="telephone" type="TelephoneType" minOccurs="0" xdb:SQLName="SHIP_TO_PHONE"/>
    60             </xs:sequence>
    61     </xs:complexType>
    62     <xs:simpleType name="moneyType">
    63             <xs:restriction base="xs:decimal">
    64                     <xs:fractionDigits value="2"/>
    65                     <xs:totalDigits value="12"/>
    66             </xs:restriction>
    67     </xs:simpleType>
    68     <xs:simpleType name="quantityType">
    69             <xs:restriction base="xs:decimal">
    70                     <xs:fractionDigits value="4"/>
    71                     <xs:totalDigits value="8"/>
    72             </xs:restriction>
    73     </xs:simpleType>
    74     <xs:simpleType name="UserType">
    75             <xs:restriction base="xs:string">
    76                     <xs:minLength value="1"/>
    77                     <xs:maxLength value="10"/>
    78             </xs:restriction>
    79     </xs:simpleType>
    80     <xs:simpleType name="RequestorType">
    81             <xs:restriction base="xs:string">
    82                     <xs:minLength value="0"/>
    83                     <xs:maxLength value="128"/>
    84             </xs:restriction>
    85     </xs:simpleType>
    86     <xs:simpleType name="CostCenterType">
    87             <xs:restriction base="xs:string">
    88                     <xs:minLength value="1"/>
    89                     <xs:maxLength value="4"/>
    90             </xs:restriction>
    91     </xs:simpleType>
    92     <xs:simpleType name="VendorType">
    93             <xs:restriction base="xs:string">
    94                     <xs:minLength value="0"/>
    95                     <xs:maxLength value="20"/>
    96             </xs:restriction>
    97     </xs:simpleType>
    98     <xs:simpleType name="PurchaseOrderNumberType">
    99             <xs:restriction base="xs:integer"/>
    100     </xs:simpleType>
    101     <xs:simpleType name="SpecialInstructionsType">
    102             <xs:restriction base="xs:string">
    103                     <xs:minLength value="0"/>
    104                     <xs:maxLength value="2048"/>
    105             </xs:restriction>
    106     </xs:simpleType>
    107     <xs:simpleType name="NameType">
    108             <xs:restriction base="xs:string">
    109                     <xs:minLength value="1"/>
    110                     <xs:maxLength value="20"/>
    111             </xs:restriction>
    112     </xs:simpleType>
    113     <xs:simpleType name="AddressType">
    114             <xs:restriction base="xs:string">
    115                     <xs:minLength value="1"/>
    116                     <xs:maxLength value="256"/>
    117             </xs:restriction>
    118     </xs:simpleType>
    119     <xs:simpleType name="TelephoneType">
    120             <xs:restriction base="xs:string">
    121                     <xs:minLength value="1"/>
    122                     <xs:maxLength value="24"/>
    123             </xs:restriction>
    124     </xs:simpleType>
    125     <xs:simpleType name="DateType">
    126             <xs:restriction base="xs:date"/>
    127     </xs:simpleType>
    128     <xs:simpleType name="CommentsType">
    129             <xs:restriction base="xs:string">
    130                     <xs:minLength value="1"/>
    131                     <xs:maxLength value="2048"/>
    132             </xs:restriction>
    133     </xs:simpleType>
    134     <xs:simpleType name="DescriptionType">
    135             <xs:restriction base="xs:string">
    136                     <xs:minLength value="1"/>
    137                     <xs:maxLength value="256"/>
    138             </xs:restriction>
    139     </xs:simpleType>
    140  </xs:schema>');
    141  begin
    142    if (dbms_xdb.existsResource(:schemaPath)) then
    143      dbms_xdb.deleteResource(:schemaPath);
    144    end if;
    145    res := dbms_xdb.createResource(:schemaPath,xmlSchema);
    146  end;
    147  /
    PL/SQL procedure successfully completed.
    SQL> begin
      2    dbms_xmlschema.registerSchema
      3    (
      4      :schemaURL,
      5      xdbURIType(:schemaPath).getClob(),
      6      FALSE,TRUE,FALSE,FALSE
      7    );
      8  end;
      9  /
    PL/SQL procedure successfully completed.
    SQL> connect local/local
    Connected.
    SQL> --
    SQL> var schemaURL varchar2(256)
    SQL> var schemaPath varchar2(256)
    SQL> --
    SQL> begin
      2    :schemaURL := 'po.xsd';
      3    :schemaPath := '/public/po.xsd';
      4  end;
      5  /
    PL/SQL procedure successfully completed.
    SQL> declare
      2    res boolean;
      3    xmlSchema xmlType := xmlType(
      4  '<xs:schema xmlns="http://xmlns.oralce.com/demo/xdb/purchaseOrder" targetNamespace="http://xmlns.oralce.com/demo/xdb/purchaseOrder"  xm
    lns:types="http://xmlns.oralce.com/demo/xdb/purchaseOrderTypes" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdb="http://xmlns.oracle.c
    om/xdb" version="1.0" xdb:storeVarrayAsTable="true">
      5     <xs:import namespace="http://xmlns.oralce.com/demo/xdb/purchaseOrderTypes" schemaLocation="poTypes.xsd"/>
      6     <xs:element name="PurchaseOrder" type="PurchaseOrderType" xdb:defaultTable="PURCHASEORDER"/>
      7     <xs:complexType name="PurchaseOrderType" xdb:SQLType="PURCHASEORDER_T">
      8             <xs:sequence>
      9                     <xs:element name="Reference" type="types:ReferenceType" xdb:SQLName="REFERENCE"/>
    10                     <xs:element name="Actions" type="types:ActionsType" xdb:SQLName="ACTIONS"/>
    11                     <xs:element name="Reject" type="types:RejectionType" minOccurs="0" xdb:SQLName="REJECTION"/>
    12                     <xs:element name="Requestor" type="types:RequestorType" xdb:SQLName="REQUESTOR"/>
    13                     <xs:element name="User" type="types:UserType" xdb:SQLName="USERID"/>
    14                     <xs:element name="CostCenter" type="types:CostCenterType" xdb:SQLName="COST_CENTER"/>
    15                     <xs:element name="ShippingInstructions" type="types:ShippingInstructionsType" xdb:SQLName="SHIPPING_INSTRUCTIONS"/>
    16                     <xs:element name="SpecialInstructions" type="types:SpecialInstructionsType" xdb:SQLName="SPECIAL_INSTRUCTIONS"/>
    17                     <xs:element name="LineItems" type="types:LineItemsType" xdb:SQLName="LINEITEMS"/>
    18             </xs:sequence>
    19     </xs:complexType>
    20     </xs:schema>');
    21  begin
    22    if (dbms_xdb.existsResource(:schemaPath)) then
    23      dbms_xdb.deleteResource(:schemaPath);
    24    end if;
    25    res := dbms_xdb.createResource(:schemaPath,xmlSchema);
    26  end;
    27  /
    PL/SQL procedure successfully completed.
    SQL> begin
      2    dbms_xmlschema.registerSchema
      3    (
      4      :schemaURL,
      5      xdbURIType(:schemaPath).getClob(),
      6      TRUE,TRUE,FALSE,TRUE
      7    );
      8  end;
      9  /
    PL/SQL procedure successfully completed.
    SQL> desc PURCHASEORDER
    Name                                      Null?    Type
    TABLE of SYS.XMLTYPE(XMLSchema "po.xsd" Element "PurchaseOrder") STORAGE Object-relational TYPE "PURCHASEORDER_T"
    SQL> desc PURCHASEORDER_T
    PURCHASEORDER_T is NOT FINAL
    Name                                      Null?    Type
    SYS_XDBPD$                                         XDB.XDB$RAW_LIST_T
    REFERENCE                                          VARCHAR2(30 CHAR)
    ACTIONS                                            GLOBAL.ACTIONS_T
    REJECTION                                          GLOBAL.REJECTION_T
    REQUESTOR                                          VARCHAR2(128 CHAR)
    USERID                                             VARCHAR2(10 CHAR)
    COST_CENTER                                        VARCHAR2(4 CHAR)
    SHIPPING_INSTRUCTIONS                              GLOBAL.SHIPPING_INSTRUCTIONS
                                                        _T
    SPECIAL_INSTRUCTIONS                               VARCHAR2(2048 CHAR)
    LINEITEMS                                          GLOBAL.LINEITEMS_T
    SQL>I'm not sure what you were trying here in your xml schema
    xdb:columnProps="NOT SUBSTITUTABLE">
    or whether or not this annotation is the source of the problem

  • 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;
    /

  • How do I get SQL Agent to perform an FTP connection through a SSIS package?

    I have created a number of SSIS packages that I am running through SQL Agent in various jobs.  I have set up a Credential / Proxy for the job steps and for the most part everything runs no problem.  The issue I have is with the step where I make
    a connection to a FTP server and download files.  In BIDS the step works fine but in SQL Agent the step times out.  I presume that it has to do with the account that it is being run under but that is what I thought the Credential / Proxy was supposed
    to handle (as it does for all the other steps).  I am running on SQL Server 2008 R2.  I have created a test job that has only one step which is to connect to the FTP server and download some text files.  I have tried utilizing package configuration
    files and have tried various ProtectionLevels to no avail.
    Anyone have any thoughts or direction for me to take?  Will continue to research and will post if I resolve this.
    Thanks, Andrew

    On the dev environment the ProtectionLevel is set to EncryptSensitiveWithUserKey and that is what I tried first on the prod server.  Subsequently I also tried utilizing a package config file (with ProtectionLevel then of DontSaveSensitive) and have
    also tried working with the ServerStorage.
    For deployment I copied the relevant dtsx files to a solution on the prod server.  I verified that the packages all had tested connections in the Connection Manager.  I have run all the packages in the BIDS on the prod server and they all worked. 
    I have created a test package from scratch on the prod server to test the ftp connection.  This test package runs from BIDS fine.  I have set the SQL Agent file to access through the file system (no luck) and have saved the package to the SSIS Packages
    and had the job step access from there (no luck either).

  • Using FTP via PL/SQL

    Hi all,
    i have the need to implement an FTP procedure and accordingly to what i found here : http://www.oracle-base.com/articles/misc/ftp-from-plsql.php i try this code:
    DECLARE
         l_conn  UTL_TCP.connection;
         l_result  PLS_INTEGER;
    BEGIN
         l_conn := UTL_TCP.open_connection('remotehost', '21');
         dbms_output.put_line('1 '||UTL_TCP.get_line(l_conn, TRUE));
         l_result := UTL_TCP.write_line(l_conn, 'USER user');
         dbms_output.put_line('2 '||UTL_TCP.get_line(l_conn, TRUE));
         l_result := UTL_TCP.write_line(l_conn, 'PASS passord');
         dbms_output.put_line('3 '||UTL_TCP.get_line(l_conn, TRUE));
         l_result := UTL_TCP.write_line(l_conn, 'cwd /some/remote/path');
         begin
              loop
                  dbms_output.put_line('4 '||UTL_TCP.get_line(l_conn, TRUE));
              end loop;
         exception
                when UTL_TCP.END_OF_INPUT then
                  null;
        end;
         l_result := UTL_TCP.write_line(l_conn, 'bye');
         UTL_TCP.close_connection(l_conn);
    END;     in order to intercept all the returning messages ... but the loop never raise exception.
    Any suggestion?
    Thanks
    Alex

    OraclePSP wrote:
    Paul Horth wrote:
    "I NEED to do ftp in a procedure, if possible"
    What business function are you trying to satisfy?Hi Paul,
    in a higher vision the all process have to :
    - transfer files in directory and subdirectory (eg. /2012/Nov , /2012/Dec, /2013/Jan, etc)
    - "check and make" the path
    - the success or errors of the entire flow has to be reported to the user
    I know that all this can be done with os command, and i already does, but i have an apex app that manage the files i would like to export.
    Is easier to report os commands result in apex vs. reproducing the command in apex directly?
    Any suggestion is welcome and appreciated.
    AlexWithout knowing more it is difficult to say what would be the best fit to your requirements but two
    approaches spring to mind.
    One is to use Unix scripts to do the ftp and write the results to a table whcih can then be interrogated by an Apex
    report as to what the result was. When you say the Apex app manages the files you want to export, do you mean
    the user picks the files to transfer? One way of doing that would be for the Unix script to read a table to see what needs
    ftping (the app would obviously set the required data up in the table).
    The second approach might be to write a Java procedure that sits in the DB and invokes the OS commands required. This procedure
    can be invoked like a normal PL/SQL procedure stored on the DB.
    Others may have other ideas.

  • What is the commands for SQL server job to ftp file to remote server?

    I created the job to bcp data out and create file on file system. after that, I need to ftp the file over to another box. how can I do it from sql server job?
    JulieShop

    I would like to suggest a SSIS package with a
    FTP Task instead.
    Olaf Helper
    [ Blog] [ Xing] [ MVP]

  • Avaibility of FTP option in SQL Developer

    Hello,
    Can any one please help me regarding the FTP option in SQL Developer.As this is avaibable in TOAD. Also let me the navigation if at all there (step in detail)
    Thankyou for your help.

    Similar thought,
    In JDeveloper, there is support for 'External Tools.' I use this feature to do things like FTP and run builds on our servers with the tcl tool 'expect'. When file support becomes available, can the external tools feature be ported over to SQL Developer? That would provide many of us with an option for adding some missing features like FTP.
    Eric

  • Appending the Destination File through FTP using PL/SQL

    One of my requirement is I have to do the ftp using PL/SQL (My database is 10g on LINUX) ,
    What I know is i can do the FTP using the UTL_TCP and UTL_FILE packages that oracle provides, but inthis case requirent is ftp and append "APPEND" to the destination file.
    this is the command I use to FTP mannualy ....
    cd C:\Temp\Source\
    ftp
    open 999.99.99.99.99
    loginID
    ThePasWord
    ascii
    append CSOURCE.DAT M:\Temp\Destination\CDESTINATION.DAT
    close
    quit
    What I want to know is how to do this through PL/SQL
    I will appreciat this ...

    I got It...
    At
    http://www.oracle-base.com/articles/9i/FTPFromPLSQL9i.php
    Only Replace
    send_command(p_conn, 'STOR ' || p_file, TRUE);
    With
    send_command(p_conn, 'APPE ' || p_file, TRUE);

  • FTP file from pl/sql in version 10.7

    Hi
    We are on Oracle apps version 10.7 and database 8.1.7.4 . I need to write a concurrent program that will generate a text file and FTP it to a remote host.
    Can this be done in pl/sql alone. Will I need to create a shell script that will make a call to the pl/sql procedure and then transfer the file ?
    Any suggestions on the approach.
    tahnkyou

    @Michaels
    D'oh! Feel foolish now, so it can, I never noticed...
    @Billy
    Well I didn't know that. I've always downloaded Winzip or Winrar and haven't seen any native uncompression functionality inside Windoze...
    I would be very interested in seeing your performance comparison, I'm not a perl fan. As xutl_udp is just a wrapper to the Java classes inside the DB's JVM, I get the feeling that perl might be a bit quicker, but then again depends on what you were doing.
    Also xutl_udp is a bit old, one of my first packages and is built to the 1.2.1 Java spec that came with 8i. Also, no multicast support as yet. I want to get back and thoroughly update it with versions for 8i to 10g, but xutl_ftp has turned out to be rather popular and everyone reports issues and/or wants more functionality and I can never seem to get it out the door!
    Anyway, enough bitchin'
    Chris
    dba.chrispoole.co.uk
    www.chrispoole.co.uk

  • How to ftp a file within PL/SQL procedure?

    Hi, all:
    Any idea of how to ftp a file within PL/SQL procedure? I have scheduled a job to periodically generate a file and want to ftp this file to another machine. I know crontab can do the ftp part, since we can send email within Oracle, I am wondering whether we can ftp within Oracle as well? Thanks a lot!

    http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:150612348067

  • Ftp from pl/sql

    Hi,
    I want to use pl/sql to ftp files from local unix server to a remote unix server.
    I'd like to have a basic set-up in place for ftp'ing, something like -
    i) open connection & login
    ii) ftp the file
    iii) ftp a zero byte trigger file
    iv) close connection
    For me using java stored procedures is not an option, I'm working on 10g and would like to do everything in pl/sql. Can someone let me know how best can this be done or point me to some good articles?
    Thanks

    This should help:
    FTP From PL/SQL.

  • SQL Loader and FTP

    Hi All,
    Is there a direct way to load data stored on an FTP server wihtout using DOS (or shell) script to upload first the data on the Oracle Server and then use sqlldr ?
    SP

    Hi All,
    Is there a direct way to load data stored on an FTP server wihtout using DOS (or shell) script to upload first the data on the Oracle Server and then use sqlldr ?
    SP

Maybe you are looking for

  • Is there a way to see and have control over who connects to your time capsule wifi network?

    Ok, have this question. Have a time capsule wifi network. Have the latest mountain lion on my mac pro. I know if you go into airport utility, and you click on the picture of my timecapsule it shows what clients are connected to my time capsule aka us

  • How Do I Secure an Emailed PDF to the Recipient's PC?

    Hi All, How can an emailed PDF be tied to a recipient's PC so that it can only be viewed on that PC? I do not want to use password control or high-end 3rd party systems, e.g. FileOpen, LockLizard, etc. I only care about restricting access (viewing),

  • Changing marker size horizontally?

    How does one increase the horizontal size of a marker? I have my song labeled with colored markers for easy visual reference (I am visually impaired) but would like to see them better, especially from a distance. For the life of me I can't find it in

  • Lead Time recalculation/update

    Hi, The requirement in my project is the following: I have a lead time for one material of 10 days. After two months I have recieved 2 PO's, one with 14 days and other with 12 days. The new lead time should be 13 days. There is any way to calculate t

  • Using table rate with scale in transportation zone

    Hi Experts, I have a question with using a rate table and scale in transportation zone. I need a scenario of calculation sheet with rate table using a transportation zone scale. In my freight order, i have many freight unit of different destinations