2012-04-18 6 views
2

Следующий код основан на популярной теме от AskTom, Export to CSVOracle 8i говорит PLS-00382: выражение неправильного типа, но я не вижу

Я сделал изменить оригинальный сценарий с некоторого кода в внутренний цикл для обработки встроенных запятых и символов кавычек.

Я не могу его скомпилировать на Oracle 8i.

Я установил значение utl_file_dir, используя DBA Studio. Затем я запустил скрипт с помощью SQL * Worksheet. Сообщаемая ошибка указывает, что проблема заключается в том, что строка 46 является проблемой.

CREATE OR REPLACE PROCEDURE dump_table_to_csv 
      (p_tname IN VARCHAR2, 
      p_dir IN VARCHAR2, 
      p_filename IN VARCHAR2) 
    IS 

    l_output  utl_file.file_type; 
    l_theCursor  INTEGER DEFAULT dbms_sql.open_cursor; 
    l_columnValue VARCHAR2(4000); 
    l_status  INTEGER; 
    l_query   VARCHAR2(1000) DEFAULT 'select * from ' || p_tname; 
    l_colCnt  NUMBER := 0; 
    l_separator  VARCHAR2(1); 
    l_descTbl  dbms_sql.desc_tab; 
    l_quote VARCHAR2(1); 

    BEGIN 
      l_output := utl_file.fopen(p_dir, p_filename, 'w', 32760); 
      -- adjust date so the format is compatible with the target system 
      -- in this case, PostgreSQL 9 
      EXECUTE IMMEDIATE 'alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss'' '; 
      -- the original version used the "rr" moniker for year. 
      -- execute immediate 'alter session set nls_date_format=''rr-mm-dd hh24:mi:ss'' '; 

      -- set up first row with column names 
      dbms_sql.parse( l_theCursor, l_query, dbms_sql.native); 
      dbms_sql.describe_columns(l_theCursor, l_colCnt, l_descTbl); 

      FOR i IN 1 .. l_colCnt LOOP 
        utl_file.put(l_output, l_separator || '"' || l_descTbl(i).col_name || '"'); 
        dbms_sql.define_column(l_theCursor, i, l_columnValue, 4000); 
        l_separator := ','; 
      END LOOP; 

      utl_file.new_line(l_output); 
      l_status := dbms_sql.EXECUTE(l_theCursor); 

      -- iterate through the data, for each row check each column 
      WHILE (dbms_sql.fetch_rows(l_theCursor) > 0) LOOP 
        l_separator := ''; 

        FOR i IN 1 .. l_colCnt LOOP 
          dbms_sql.column_value(l_theCursor, i, l_columnValue); 
          -- 
          -- if the separator or quote is embedded in the value then enclose in double-quotes 
          IF INSTR(l_columnValue, ',') != 0 OR INSTR(l_columnValue, '"') THEN 
            l_quote := '"'; 
            -- double any/all embedded quotes 
            l_columnValue := REPLACE(l_columnValue,'"','""'); 
          ELSE 
            l_quote := ''; 
          END IF; 
          l_columnValue := l_separator || l_quote || l_columnValue || l_quote; 
          -- 
          -- write the value to disk 
          utl_file.put(l_output, l_separator || l_columnValue); 
          l_separator := ','; 
        END LOOP; 

        utl_file.new_line(l_output); 
      END LOOP; 

      dbms_sql.close_cursor(l_theCursor); 
      utl_file.fclose(l_output); 

      EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; 

    EXCEPTION 
      WHEN OTHERS THEN 
        EXECUTE IMMEDIATE 'alter session set nls_date_format=''dd-MON-yy'' '; 
        RAISE; 
    END; 
+1

Oracle 8i был уволен и поставлен «из эксплуатации» десять лет назад. Почему вы используете такую ​​старую и неподдерживаемую версию? –

+1

При всем уважении проект * является * для выхода на старый сервер. – Mophilly

ответ

6

Вы пропускаете != 0 для второго instr() вызова в строке 46:

if instr(l_columnValue, ',') != 0 or instr(l_columnValue, '"') then 

должно быть:

if instr(l_columnValue, ',') != 0 or instr(l_columnValue, '"') != 0 then 
+0

Спасибо. Это, конечно, работало как прелесть. В стороне, я собираюсь сорвать себя за то, что не заметил упущения. – Mophilly

2

Что линия Oracle приподняв ошибку?

Первая ошибка, которая выскакивает у меня есть линия

IF INSTR(l_columnValue, ',') != 0 OR INSTR(l_columnValue, '"') THEN 

INSTR возвращает число. Первая часть вашего условия сравнивает вывод INSTR с номером. Второе не ... это было бы справедливо только в том случае, если INSTR возвратил логическое значение. Похоже, вы хотите

IF INSTR(l_columnValue, ',') != 0 OR INSTR(l_columnValue, '"') != 0 THEN 
+0

Ваш ответ тоже верный. Благодарю вас за публикацию. – Mophilly