Avatar billede mundt Nybegynder
29. oktober 2001 - 08:04 Der er 13 kommentarer og
2 løsninger

dbms_lob.write

Jeg har udviklet et program som skal køre på en Oracle server i Oracles job-scheduler dbms_job.

Programmet fungerer og jeg har nu brug for at kunne skrive til logfil hvornår jobbet startede og sluttede og yderligere hvis jobbet fejler et tidspunkt for hvornår og hvilket fejl.

Jeg har lavet nedenstående testprocedure som skal skrive til en fil:

CREATE OR REPLACE PROCEDURE writeDataToFile IS
    v_file_loc    BFILE;
    v_buffer      VARCHAR2(26);
    v_amount      BINARY_INTEGER := 26;
    v_position    INTEGER := 1;
    i              INTEGER;

  BEGIN
    v_file_loc := BFILENAME (\'STOPLIST\', \'TimeLog.log\');
    /* Fill the buffer with data to write to the LOB: */
    v_buffer := to_char(sysdate);

    FOR i IN 1..3 LOOP
      DBMS_LOB.WRITE (v_file_loc, 30, 1, v_buffer);
      /* Fill the buffer with more data to write to the LOB: */
      v_buffer := to_char(sysdate) || to_char(i);
      v_position := v_position + v_amount;
    END LOOP;
    /* Closing the LOB is mandatory if you have opened it: */
    DBMS_LOB.FILECLOSE (v_file_loc);
  END;

Jeg har oprettet STOPLIST directory.

Når jeg forsøger at kompilere får jeg følgende fejlbesked:

PLS-00306: wrong number or types of arguments in call to \'WRITE\'

Umiddelbart kan jeg ikke se at jeg skal kunne udelade nogle argumenter i dbms_lob.write.

Er der nogen som kan hjælpe?
Avatar billede teepee Nybegynder
29. oktober 2001 - 08:15 #1
I følge spec\'en skal sidste parameter være en raw. Kan du prøve at lave din varchar2 om til raw.
Avatar billede pgroen Nybegynder
29. oktober 2001 - 08:26 #2
Brug UTL_FILE pakken i stedet for; DBMS_LOB er beregnet til operationer på BLOB\'er og lign...
Avatar billede mundt Nybegynder
29. oktober 2001 - 08:31 #3
Kan jeg få den til udelukkende til at køre på serveren. Grunden til at jeg spørger er jeg erindrer noget om at man skal ændre i en lokal fil som henviser til den fil man ønsker at læse/skrive til. I alle tilfælde må du meget gerne vise et eksempel på hvorledes man skriver til en fil med UTL_FILE :o) . 
Avatar billede mundt Nybegynder
29. oktober 2001 - 08:36 #4
Jeg får stadig samme fejl efter at have ændret min procedure til nedenstående:

  CREATE OR REPLACE PROCEDURE writeDataToFile IS
    v_file_loc    BFILE;
    v_buffer      RAW(1024);
    v_amount      BINARY_INTEGER := 26;
    v_position    INTEGER := 1;
    i              INTEGER;

  BEGIN

    v_file_loc := BFILENAME (\'STOPLIST\', \'TimeLog.log\');
    v_buffer := \'Test\';

    FOR i IN 1..3 LOOP
      DBMS_LOB.WRITE (v_file_loc, 30, 1, v_buffer);
      /* Fill the buffer with more data to write to the LOB: */
      v_buffer := \'Test2\';
      v_position := v_position + v_amount;
    END LOOP;
    /* Closing the LOB is mandatory if you have opened it: */
    DBMS_LOB.FILECLOSE (v_file_loc);

  END;

Avatar billede teepee Nybegynder
29. oktober 2001 - 08:42 #5
Et utl_file eksempel fra metalink:

Create or replace procedure write_emp as
emp_data UTL_FILE.FILE_TYPE;
BEGIN
--Open the file
emp_data := UTL_FILE.FOPEN (\'C:\\DB_UTL\',\'employees.txt\', \'W\', 4096);
--write out empno
UTL_FILE.PUT_LINE(emp_data, \'[EMPNO]\');
UTL_FILE.PUT (emp_data, \'EMPNO=\');
for emp in ( select empno from emp) loop
UTL_FILE.PUT (emp_data, emp.empno||\'|\');
end loop;
UTL_FILE.new_line (emp_data);
--Write out a list of employee IDs and names, salary etc.
FOR emp IN ( select * FROM emp) LOOP
UTL_FILE.PUT_LINE (emp_data, \'********************************\');
UTL_FILE.PUT_LINE (emp_data, \'EMPNO= \'||emp.empno);
UTL_FILE.PUT_LINE (emp_data, \'ENAME= \'||emp.ename);
UTL_FILE.PUT_LINE (emp_data, \'JOB= \'||emp.JOB);
UTL_FILE.PUT_LINE (emp_data, \'MGR= \'||emp.MGR);
UTL_FILE.PUT_LINE (emp_data, \'HIREDATE= \'||emp.HIREDATE);
UTL_FILE.PUT_LINE (emp_data, \'SAL= \'||emp.SAL);

if emp.comm is not null then
UTL_FILE.PUT_LINE (emp_data, \'COMM= \'||EMP.COMM);
end if;
UTL_FILE.PUT_LINE (emp_data, \'DEPTNO= \'||emp.DEPTNO);
UTL_FILE.PUT_LINE (emp_data, \' \');
END LOOP;
--Close the file
UTL_FILE.FCLOSE (emp_data);
end;
/
Avatar billede pgroen Nybegynder
29. oktober 2001 - 09:14 #6
Nej, du skal ikke pille i nogen lokale file,
det du tænker på, er nok at du skal rette i INIT.ORA, for at få adgang til at skrive i et givent directory, se evt. nedenstående fra Metalink:


Directory Names
===============

For UTL_FILE\'s procedures to access server directories the directories to
be accessed must be specified in the init.ora file, for example :

UTL_FILE_DIR=E:\\LOGDIR

Quotes and a trailing \\ are not necessary.

Avatar billede mundt Nybegynder
29. oktober 2001 - 09:50 #7
Jeg har simplificeret proceduren en smule:

Create or replace procedure write_emp as
  emp_data UTL_FILE.FILE_TYPE;
  v_error_code      Number;
  v_error_message  Varchar2(255);

  BEGIN
  --Open the file
  emp_data := UTL_FILE.FOPEN (\'D:\\ARKIVDREV\\FILES\',\'ErrorLog.log\', \'W\', 4096);
  --write out empno
  UTL_FILE.PUT_LINE(emp_data, to_char(sysdate));
  UTL_FILE.new_line (emp_data);
  UTL_FILE.PUT_LINE(emp_data, to_char(sysdate));

  --Close the file
  UTL_FILE.FCLOSE (emp_data);
 
 
  Exception
 
  When others Then
        Commit;
      v_error_code := Sqlcode;
      v_error_message := Sqlerrm;
      dbms_output.put_line(\'Fejlkode: \' || to_char(v_error_code));
      dbms_output.put_line(\'Fejltekst: \' || v_error_message);
end;
/

Jeg kan godt kompilere men får følgende fejl når jeg eksekverer:


FEJL i linie 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at \"SYS.UTL_FILE\", line 98
ORA-06512: at \"SYS.UTL_FILE\", line 192
ORA-06512: at \"ARKIV.WRITE_EMP\", line 5
ORA-06512: at line 1
Avatar billede pgroen Nybegynder
29. oktober 2001 - 10:00 #8
Øhm, nå - har du rettet UTL_FILE_DIR i INIT.ORA, og restartet basen ?

Det kunne være, fordi du ikke har skriverettigheder til D:\\ARKIVDREV\\FILES...
Avatar billede pgroen Nybegynder
29. oktober 2001 - 10:02 #9
Øhm, nå - har du rettet UTL_FILE_DIR i INIT.ORA, og restartet basen ?

Det kunne være, fordi du ikke har skriverettigheder til D:\\ARKIVDREV\\FILES...
Avatar billede pgroen Nybegynder
29. oktober 2001 - 10:03 #10
Og bemærk i øvrigt, at det ikke er DIT (klientens) D:drev der skrives til, men serverens.
Avatar billede mundt Nybegynder
29. oktober 2001 - 10:08 #11
Jeg har desværre ikke mulighed for at genstarte databasen i dag.

Men hvad nu når jeg ligger dette I Oracles jobscheduler (dbms_job) hvilken kører udelukkende på serveren - kan den så godt skrive til den angivne sti, når jeg nu kun ændrer init.ora lokalt?
Avatar billede mundt Nybegynder
29. oktober 2001 - 10:10 #12
Ja, det er også fint nok - for det er en fil som er placeret på serven.
Avatar billede pgroen Nybegynder
29. oktober 2001 - 10:24 #13
Jeg er ikke helt med på, hvad du mener med at ændre init.ora lokalt; det er naturligvis på serveren den skal ændres...
Avatar billede mundt Nybegynder
29. oktober 2001 - 10:26 #14
Ja selvfølgelig, det var mig der ikke lige tænkte mig om. Det prøver jeg og vender tilbage senere.
Avatar billede mundt Nybegynder
31. oktober 2001 - 13:57 #15
Det virker nu efter af at jeg har tilføjet

UTL_FILE_DIR=#PATH\"

i init.ora på databaseserveren.

Min testfil ser ud som nedenstående:

procedure write_emp as
  emp_data UTL_FILE.FILE_TYPE;
  v_error_code      Number;
  v_error_message  Varchar2(255);

  BEGIN
  --Open the file
  emp_data := UTL_FILE.FOPEN (\'D:\\ARKIVDREV\\FILES\',\'ErrorLog.log\', \'W\', 4096);
  --write out empno
  UTL_FILE.PUT_LINE(emp_data, to_char(sysdate));
  UTL_FILE.new_line (emp_data);
  UTL_FILE.PUT_LINE(emp_data, to_char(sysdate));

  --Close the file
  UTL_FILE.FCLOSE (emp_data);


  Exception

  When others Then
        Commit;
      v_error_code := Sqlcode;
      v_error_message := Sqlerrm;
      dbms_output.put_line(\'Fejlkode: \' || to_char(v_error_code));
      dbms_output.put_line(\'Fejltekst: \' || v_error_message);
end;

Tak for hjælpen!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester