web-dev-qa-db-fra.com

La procédure UTL_FILE.FOPEN () n'accepte pas le chemin du répertoire?

J'essaie d'écrire dans un fichier stocké dans le lecteur c:\nommé vin1.txt

> 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

Voici le code

  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
21
Vineet

Depuis Oracle 9i, il existe deux manières de déclarer un répertoire à utiliser avec UTL_FILE. 

La méthode la plus ancienne consiste à définir le paramètre INIT.ORA UTL_FILE_DIR. Nous devons redémarrer la base de données pour qu'une modification prenne effet. La valeur peut ressembler à n'importe quelle autre variable PATH; il accepte les wildcards. Utiliser cette approche signifie passer le chemin du répertoire ...

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

L’approche alternative consiste à déclarer un objet de répertoire.

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

grant read, write on directory temp_dir to vineet
/

Les objets de répertoire exigent le chemin d'accès exact au fichier et n'acceptent pas les caractères génériques. Dans cette approche, nous passons le nom d'objet d'annuaire ...

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

UTL_FILE_DIR est obsolète car il est intrinsèquement peu sécurisé. Tous les utilisateurs ont accès à tous les répertoires du système d'exploitation spécifiés dans le chemin, alors que les privilèges de lecture et d'écriture peuvent être accordés séparément à des utilisateurs individuels. De plus, avec les objets Directory, nous pouvons ajouter, supprimer ou modifier des répertoires sans faire rebondir la base de données.

Dans les deux cas, l'utilisateur Oracle du système d'exploitation doit disposer des privilèges de lecture et/ou d'écriture sur le répertoire du système d'exploitation . Si cela n’est pas évident, cela signifie le répertoire doit être visible à partir du serveur de base de données . Nous ne pouvons donc utiliser aucune de ces approches pour exposer un répertoire de notre PC local à un processus exécuté sur un serveur de base de données distant. Les fichiers doivent être téléchargés sur le serveur de base de données ou sur un lecteur réseau partagé.


Si l'utilisateur Oracle du système d'exploitation ne dispose pas des privilèges appropriés sur le répertoire du système d'exploitation ou si le chemin spécifié dans la base de données ne correspond pas à un chemin réel, le programme lève cette exception:

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

Le texte OERR de cette erreur est assez clair:

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.
35
APC

N'oubliez pas également que le chemin d'accès au fichier se trouve sur le serveur Oracle actuel et non sur un ordinateur de développement local susceptible d'appeler votre procédure stockée. Ceci est probablement très évident, mais il convient de se rappeler de cela.

6
Josh P

Vous devez enregistrer le répertoire avec Oracle. fopen prend le nom d'un objet d'annuaire, pas le chemin. Par exemple:

(vous devrez peut-être vous connecter en tant que SYS pour les exécuter)

CREATE DIRECTORY MY_DIR AS 'C:\';

GRANT READ ON DIRECTORY MY_DIR TO SCOTT;

Ensuite, vous pouvez vous y référer dans l’appel à fopen:

execute sal_status('MY_DIR','vin1.txt');
4
Jeffrey Kemp

Pour utl_file.open (emplacement, nom de fichier, mode), nous devons donner un nom de répertoire pour l’emplacement mais pas le chemin. Par exemple: DATA_FILE_DIR, il s'agit du nom du répertoire et extrayez le chemin du répertoire pour ce nom de répertoire particulier.

1
sujini

Vous devez demander à votre administrateur de base de données de modifier le fichier init.ora en ajoutant le répertoire auquel vous souhaitez accéder au paramètre 'utl_file_dir'. Votre instance de base de données devra ensuite être arrêtée et redémarrée, car init.ora est lu uniquement lors de la mise à niveau de la base de données.

Vous pouvez afficher (mais pas modifier) ​​ce paramètre en exécutant la requête suivante:

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

Partager et profiter.

0
Bob Jarvis

Le nom du répertoire semble être sensible à la casse. J'ai rencontré le même problème mais lorsque j'ai fourni le nom du répertoire en majuscules, cela a fonctionné.

0
Shafqat Ali