2010-05-01 43 views
19

Sto provando a scrivere in un file memorizzato in c: \ unità chiamata vin1.txt e ottenendo questo errore. Si prega di suggerire!La procedura UTL_FILE.FOPEN() non accetta il percorso per la directory?

> ERROR at line 1: ORA-29280: invalid 
> directory path ORA-06512: at 
> "SYS.UTL_FILE", line 18 ORA-06512: at 
> "SYS.UTL_FILE", line 424 ORA-06512: at 
> "SCOTT.SAL_STATUS", line 12 ORA-06512: 
> at line 1 

Ecco il codice

create or replace procedure sal_status 
    (
    p_file_dir IN varchar2, 
    p_filename IN varchar2) 
    IS 
    v_filehandle utl_file.file_type; 
    cursor emp Is 
     select * from employees 
     order by department_id; 
    v_dep_no departments.department_id%TYPE; 
    begin 
     v_filehandle :=utl_file.fopen(p_file_dir,p_filename,'w');--Opening a file 
     utl_file.putf(v_filehandle,'SALARY REPORT :GENERATED ON %s\n',SYSDATE); 
     utl_file.new_line(v_filehandle); 
     for v_emp_rec IN emp LOOP 
      v_dep_no :=v_emp_rec.department_id; 
      utl_file.putf(v_filehandle,'employee %s earns:s\n',v_emp_rec.last_name,v_emp_rec.salary);      
     end loop; 
     utl_file.put_line(v_filehandle,'***END OF REPORT***'); 
     UTL_FILE.fclose(v_filehandle); 
    end sal_status; 

execute sal_status('C:\','vin1.txt');--Executing 

risposta

32

Poiché Oracle 9i lì sono due modi o dichiarando una directory da utilizzare con UTL_FILE.

Il metodo precedente consiste nell'impostare il parametro INIT.ORA UTL_FILE_DIR. Dobbiamo riavviare il database affinché una modifica abbia effetto. Il valore può piacere a qualsiasi altra variabile PATH; accetta i caratteri jolly. Utilizzare questo approccio significa passare il percorso della directory ...

UTL_FILE.FOPEN('c:\temp', 'vineet.txt', 'W'); 

L'approccio alternativo è quello di dichiarare un oggetto directory.

create or replace directory temp_dir as 'C:\temp' 
/

grant read, write on directory temp_dir to vineet 
/

Gli oggetti di directory richiedono l'esatto percorso del file e non accettano caratteri jolly. In questo approccio abbiamo passare il nome dell'oggetto directory ...

UTL_FILE.FOPEN('TEMP_DIR', 'vineet.txt', 'W'); 

L'UTL_FILE_DIR è deprecato, perché è intrinsecamente insicuro - tutti gli utenti hanno accesso a tutte le directory del sistema operativo specificate nel percorso, mentre di lettura e scrittura possono de concesso in modo discreto ai singoli utenti. Inoltre, con gli oggetti Directory possiamo aggiungere, rimuovere o cambiare directory senza rimbalzare il database.

In entrambi i casi, l'utente del sistema operativo oracle deve disporre dei privilegi di lettura e/o scrittura nella directory del sistema operativo. Nel caso non sia ovvio, ciò significa che la directory deve essere visibile dal server di database. Quindi non possiamo usare entrambi gli approcci per esporre una directory sul nostro PC locale a un processo in esecuzione su un server di database remoto. I file devono essere caricati sul server del database o su un'unità di rete condivisa.


Se l'utente oracle sistema operativo non dispone di privilegi appropriati nella directory OS, o se il percorso specificato nel database non corrisponde a un percorso effettivo, il programma scagliare questa eccezione:

ORA-29283: invalid file operation 
ORA-06512: at "SYS.UTL_FILE", line 536 
ORA-29283: invalid file operation 
ORA-06512: at line 7 

L'OERR testo per questo errore è abbastanza chiaro:

29283 - "invalid file operation" 
*Cause: An attempt was made to read from a file or directory that does 
      not exist, or file or directory access was denied by the 
      operating system. 
*Action: Verify file and directory access privileges on the file system, 
      and if reading, verify that the file exists. 
+0

Puoi concatenare con altre directory? ad esempio: UTL_FILE.FOPEN ('TEMP_DIR' || '/ otherFolder', 'vineet.txt', 'W'); Voglio sapere se è possibile. PERCORSO DEL SERVER FTP/.../... / – delive

0

È necessario avere il vostro DBA modificare il file init.ora, aggiungendo la directory che si desidera accedere al parametro 'utl_file_dir'. L'istanza del database dovrà quindi essere arrestata e riavviata poiché init.ora viene letto solo quando il database viene richiamato.

È possibile visualizzare (ma non modificare) questo parametro eseguendo la seguente query:

SELECT * 
    FROM V$PARAMETER 
    WHERE NAME = 'utl_file_dir' 

Condividere e godere.

3

È necessario register the directory con Oracle. fopen prende il nome di un oggetto directory, non il percorso. Per esempio:

(potrebbe essere necessario effettuare il login come SYS per eseguire questi)

CREATE DIRECTORY MY_DIR AS 'C:\'; 

GRANT READ ON DIRECTORY MY_DIR TO SCOTT; 

Quindi, è possibile fare riferimento ad esso nella chiamata a fopen:

execute sal_status('MY_DIR','vin1.txt'); 
+0

Nota: questo metodo non è disponibile nelle versioni precedenti di Oracle (penso 9 prima), in cui potrebbe essere necessario impostare utl_file_dir. Penso che –

5

da non dimenticare, inoltre, che il percorso per il file si trova sulla macchina server Oracle effettivo e non qualsiasi loca l computer di sviluppo che potrebbe chiamare la procedura memorizzata. Questo è probabilmente molto ovvio ma qualcosa che dovrebbe essere ricordato.

1

Per utl_file.open (posizione, nome file, modalità), è necessario fornire il nome della directory per la posizione ma non il percorso. Ad esempio: DATA_FILE_DIR, questo è il nome della directory e controlla il percorso della directory per quel particolare nome di directory.

0

Il nome della directory sembra essere case sensitive. Ho affrontato lo stesso problema ma quando ho fornito il nome della directory in maiuscolo ha funzionato.