出现错误 29285。00000 -“文件写入错误” *原因:尝试 FFLUSH 时无法写入、刷新或关闭文件

Posted

技术标签:

【中文标题】出现错误 29285。00000 -“文件写入错误” *原因:尝试 FFLUSH 时无法写入、刷新或关闭文件【英文标题】:Getting error 29285. 00000 - "file write error" *Cause: Failed to write to, flush, or close a file when trying to FFLUSH 【发布时间】:2018-12-04 04:31:57 【问题描述】:

作为项目的一部分,我正在处理我们公司使用的 peoplesoft 记录和字段的数据映射。我必须记录超过 25,000 个字段,但它变得乏味,并且如果我以正常方式进行操作,将花费更多时间。因此,我编写了一个存储过程来减少记录翻译值的一些工作。

这是我的存储过程的代码:

CREATE OR REPLACE PROCEDURE SP_DATAMAPPINGINFO(exportdir varchar2) AS 
TYPE EmpCurTyp IS REF CURSOR;
newrow_cursor    EmpCurTyp;
txtable_cursor EmpCurTyp;
txtabfieldname_cursor EmpCurTyp;

file UTL_FILE.FILE_TYPE;
queryfile UTL_FILE.FILE_TYPE;

recname varchar2(40);
recdescr varchar2(200);
fieldnum number(3);
fieldname varchar2(40);
fieldescr varchar2(2000);
keyflag varchar2(1);
fieldtype varchar2(20);
distinctcount number(10);
boolfieldFirst number(1);
boolfieldSecond number(1);
boolfieldCLOB number(1);
boolfieldBLOB number(1);
boolTxTabName number(1);
txtabfieldname varchar2(40);

query1_str varchar(300);
query2_str varchar(300);
query3_str varchar(300);
query4_str varchar(300);
queryTxTabExist varchar(300);
queryTxVwExist varchar(300);

fieldvalue varchar2(500);
hyphen varchar2(5);
txvalue varchar2(500);
fielduse CLOB;
fielduseLength INTEGER;
fieldinfo CLOB;
fieldinfoLength INTEGER;
pos INTEGER := 1;
buffer VARCHAR2(32767);
amount BINARY_INTEGER := 32760;

tablename varchar2(40);
intertxtabname varchar2(30);
txtablename varchar2(40);
txTabNameCheck number(1);
txVwNameCheck number(1);

dir varchar2(30);
file_name varchar2(30);
query_File varchar2(30);

CURSOR get_fields is
        select A.RECNAME as "Record", A.RECDESCR as "Record Description"
        , B.FIELDNUM as "FieldNum", B.FIELDNAME as "Field", C.DESCRLONG as "Field Description", CASE WHEN
        EXISTS(select K.FIELDNAME FROM PSRECFLDDBKEYVW K WHERE K.RECNAME = A.RECNAME AND K.FIELDNAME=B.FIELDNAME)
        THEN 'Y' ELSE 'N' END as "Key (Y/N)", DECODE (C.FIELDTYPE,
                 0, 'Character',
                 1, 'LongChar',
                 2, 'Number',
                 3, 'Signed Number',
                 4, 'Date',
                 5, 'Time',
                 6, 'DateTime',
                 8, 'ImageOrAttachment',
                 9, 'Image Reference',
                 'Unknown') as "FieldType"
        FROM PSRECDEFN A, PSRECFIELDDB B LEFT JOIN PSDBFIELD C ON (B.FIELDNAME = C.FIELDNAME)
        WHERE B.RECNAME = A.RECNAME
        AND A.RECNAME IN (select R.RECNAME from PSRECDEFN R, DBA_TABLES T
        WHERE ('PS_'||R.RECNAME=T.TABLE_NAME)
        AND T.NUM_ROWS > 0
        AND R.RECTYPE=0)
        order by A.RECNAME, B.FIELDNUM;

BEGIN

dir := exportdir;
file_name := 'peoplesoft_datamapping.csv';

query_File := 'peoplesoftQuery.txt';

file := UTL_FILE.FOPEN(dir, file_name, 'w', 32767);
queryfile := UTL_FILE.FOPEN(dir, query_File, 'w', 32767);

OPEN get_fields;
    LOOP
    FETCH get_fields INTO recname, recdescr, fieldnum, fieldname, fieldescr, keyflag, fieldtype;


    fielduse := '';
    fieldinfo := '';
    tablename := 'PS_' || recname;
    hyphen := ' - ';
    fieldvalue := '';
    txvalue := '';
    intertxtabname := '';
    txtablename := '';
    boolfieldFirst := 0;
    boolfieldSecond := 0;
    boolfieldCLOB := 0;
    boolfieldBLOB := 0;
    boolTxTabName := 0;
    txTabNameCheck := 0;
    txVwNameCheck := 0;
    pos := 1;
    
    
    IF (fieldtype = 'LongChar') THEN
        boolfieldCLOB := 1;
    ELSIF (fieldtype = 'ImageOrAttachment') THEN
        boolfieldBLOB := 1;
    END IF;

    IF (fieldname NOT LIKE '%EMPLID%' and fieldname NOT LIKE '%DESCR%' and fieldname NOT LIKE '%COMMENT%' and fieldtype <> 'Date') THEN
        query1_str := 'select NVL(TRIM(RI.EDITTABLE), ''isnull'') FROM PSRECDEFN RD, PSRECFIELDDB RI WHERE RD.RECNAME = RI.RECNAME 
        AND RD.RECNAME = ''' || recname || ''' AND RI.FIELDNAME = ''' || fieldname || '''';

        execute immediate query1_str into intertxtabname;
        
        queryTxTabExist := 'SELECT COUNT(TABLE_NAME) FROM ALL_TABLES where TABLE_NAME=''PS_' || intertxtabname || '''';
        execute immediate queryTxTabExist into txTabNameCheck;
        if (txTabNameCheck = 1) THEN
            boolTxTabName := 1;
        ELSIF (txTabNameCheck = 0) THEN
            queryTxVwExist := 'SELECT COUNT(VIEW_NAME) FROM ALL_VIEWS where VIEW_NAME=''PS_' || intertxtabname || '''';
            execute immediate queryTxVwExist into txVwNameCheck;
            if (txVwNameCheck = 1) THEN
                boolTxTabName := 1;
            ELSIF (txVwNameCheck = 0) THEN
                queryTxTabExist := 'SELECT COUNT(TABLE_NAME) FROM ALL_TABLES where TABLE_NAME=''' || intertxtabname || '''';
                execute immediate queryTxTabExist into txTabNameCheck;
                if (txTabNameCheck = 1) THEN
                    boolTxTabName := 5;
                ELSIF (txTabNameCheck = 0) THEN
                    queryTxVwExist := 'SELECT COUNT(VIEW_NAME) FROM ALL_VIEWS where VIEW_NAME=''' || intertxtabname || '''';
                    execute immediate queryTxVwExist into txVwNameCheck;
                    if (txVwNameCheck = 1) THEN
                        boolTxTabName := 5;
                    ELSIF (txVwNameCheck = 0) THEN
                        boolTxTabName := 0;
                    ELSE
                        dbms_output.put_line ('Incorrect transaction table count');
                    END IF;
                END IF;
            ELSE
                dbms_output.put_line ('Incorrect transaction table count');
            END IF;
        ELSE
            dbms_output.put_line ('Incorrect transaction table count');
        END IF;
        
        query2_str := 'select count(distinct T.' || fieldname || ') FROM ' || tablename || ' T';

        IF (intertxtabname <> 'isnull' and boolTxTabName <> 0) THEN
            query4_str := 'select B.FIELDNAME FROM PSRECDEFN A, PSRECFIELDDB B WHERE B.RECNAME=A.RECNAME AND A.RECNAME=''' || intertxtabname
            || ''' ORDER BY B.FIELDNAME';
            OPEN txtabfieldname_cursor for query4_str;
                LOOP
                FETCH txtabfieldname_cursor into txtabfieldname;
                if (txtabfieldname='DESCR') THEN
                    boolfieldFirst := 1;
                ELSIF (txtabfieldname = fieldname) THEN
                    boolfieldSecond := 1;
                END IF;
                EXIT WHEN txtabfieldname_cursor%NOTFOUND;
                END LOOP;
            CLOSE txtabfieldname_cursor;
            IF (boolfieldFirst = 1 and boolfieldSecond = 1 and boolfieldCLOB = 0 and boolfieldBLOB = 0) THEN
                IF (boolTxTabName = 1) THEN
                    txtablename := 'PS_' || intertxtabname;
                ELSIF (boolTxTabName = 5) THEN
                    txtablename := intertxtabname;
                ELSE
                    dbms_output.put_line ('Incorrect case traversal. Check logic');
                END IF;
                query3_str := 'select distinct T.' || fieldname || ', TR.DESCR FROM ' || tablename || ' T left join ' || txtablename || ' TR ON T.' 
                || fieldname || ' = TR.' || fieldname || ' order by T.' || fieldname;
            ELSIF (boolfieldFirst = 0) THEN
                query3_str := 'noDescrField';
            ELSIF (boolfieldSecond = 0) THEN
                query3_str := 'sameFieldNotPresentInTx';
            ELSIF (boolfieldCLOB = 1) THEN
                query3_str := 'CLOB_Type_Skipping';
            ELSIF (boolfieldBLOB = 1) THEN
                query3_str := 'BLOB_Type_Skipping';
            END IF;
        ELSE
            IF (boolfieldCLOB = 1) THEN
                query3_str := 'CLOB_Type_Skipping';
            ELSIF (boolfieldBLOB = 1) THEN
                query3_str := 'BLOB_Type_Skipping';
            ELSE
                txtablename := '';
                query3_str := 'select distinct DT.' || fieldname || ', DTR.XLATLONGNAME FROM ' || tablename || ' DT left join PSXLATITEM DTR on 
                (DTR.FIELDNAME = ''' || fieldname || ''' and DT.' || fieldname || ' = DTR.FIELDVALUE) order by DT.' || fieldname;
            END IF;
        END IF;    

        UTL_FILE.PUT_LINE(queryfile, query3_str);
        
        IF (query3_str <> 'noDescrField' and query3_str <> 'sameFieldNotPresentInTx' and query3_str <> 'CLOB_Type_Skipping' and query3_str <> 'BLOB_Type_Skipping') THEN
            execute immediate query2_str into distinctcount;
        END IF;

        if(distinctcount > 150) THEN
            fielduse := 'More than 150';
        ELSIF (query3_str = 'noDescrField') THEN
            fielduse := 'noDescrField';
        ELSIF (query3_str = 'sameFieldNotPresentInTx') THEN
            fielduse := 'sameFieldNotPresentInTx';
        ELSIF (query3_str = 'CLOB_Type_Skipping') THEN
            fielduse := 'CLOB_Type_Skipping';
        ELSIF (query3_str = 'BLOB_Type_Skipping') THEN
            fielduse := 'BLOB_Type_Skipping';
        ELSE
            OPEN newrow_cursor FOR query3_str;
                LOOP
                FETCH newrow_cursor INTO fieldvalue, txvalue;
                fielduse := fielduse || fieldvalue || ' - ' || txvalue || '; ';
                EXIT WHEN newrow_cursor%NOTFOUND;
                END LOOP;
            CLOSE newrow_cursor;
        END IF;

    ELSE
        fielduse := 'SKIPPING';
    END IF;
    
    fieldinfo := recname || ',' || recdescr || ',' || fieldnum || ',' || fieldname || ',' || fieldescr || ',' || keyflag || ',' || fieldtype || ',' || fielduse;
    
    fieldinfoLength := length(fieldinfo);
    IF (fieldinfoLength > 32766) THEN
        WHILE pos < fieldinfoLength LOOP
            dbms_lob.read(fieldinfo, amount, pos, buffer);
            UTL_FILE.PUT(file, buffer);
            UTL_FILE.FFLUSH(file);
            pos := pos + amount;
        END LOOP;
        UTL_FILE.NEW_LINE(file);
    ELSE
        UTL_FILE.PUT_LINE(file, fieldinfo);
    END IF;
    
    fielduse := '';
    fieldinfo := '';
    pos := 1;

    END LOOP;
    
    UTL_FILE.FCLOSE(file);
CLOSE get_fields;

NULL;
END SP_DATAMAPPINGINFO;

看来我的数据逻辑正确,但我可能没有正确使用 UTL_FILE.FFLUSH 函数,因为当代码命中该函数时,我收到以下错误(我已从该代码中删除了几个 cmets,因此行号可能不匹配)。它总是发生在同一点,因为当错误发生时输出文件总是具有相同的大小。它发生在代码第一次为 IF (fieldinfoLength &gt; 32766) if-else 语句评估为真时。在执行 UTL_FILE.PUT_LINE 之前它工作正常,没有任何问题。

从第 11 行开始的错误命令 -

开始 SP_DATAMAPPINGINFO ('DIR');结束;

错误报告-

ORA-29285: 文件写入错误

ORA-06512:在“SYS.UTL_FILE”第 183 行

ORA-06512:在“SYS.UTL_FILE”,第 1169 行

ORA-06512:在“SYSADM.SP_DATAMAPPINGINFO”,第 240 行

ORA-06512:在第 1 行

    00000 - “文件写入错误”

*原因:无法写入、刷新或关闭文件。

*操作:验证文件是否存在、是否可访问以及是否以写入或追加模式打开。

我正在努力寻找这背后的原因,因为我认为我正确使用了 CLOB、UTL_PUT 和 UTL_FFLUSH 函数。任何帮助表示赞赏。如果您发现任何其他明显的错误,请指出。

【问题讨论】:

【参考方案1】:

似乎您正在提供函数“DIR”而不是实际目录。

【讨论】:

不,事实并非如此。正如我在帖子中所说,它写入指定文件中的目录,并且当文件达到一定大小时总是在同一个地方失败。 DIR 是我在执行过程之前创建的目录变量。如果是这样的话,我认为会有一个不同的错误,比如这个 - ORA-29283: invalid file operation BEGIN SP_DATAMAPPINGINFO ('DIR'); 另有建议 我怎样才能得到我在代码中指定的文件中的输出呢?您可以将目录作为变量传递。看到这些:***.com/questions/2751113/…dba-oracle.com/t_ora_29283_invalid_file_operation.htm 你的意思是一个目录对象,我被你对“变量”的使用弄糊涂了,对不起。

以上是关于出现错误 29285。00000 -“文件写入错误” *原因:尝试 FFLUSH 时无法写入、刷新或关闭文件的主要内容,如果未能解决你的问题,请参考以下文章

电脑出现0xc00000ba程序失败怎么弄

29283. 00000 - “无效的文件操作”

我的电脑正常启动,怎么每次都会出现“0xc00000ba”失败

应用程序无法正常启动0xc00000ba怎么办啊

oracle日期转换报ORA-01810: 格式代码出现两次 01810. 00000 -  "format code appears twice"

00984. 00000 - “此处不允许列”