2017-05-25 207 views
0

我正在将数据从oracle数据库迁移到postgresql数据库。我遇到了一个问题,我使用存储过程从oracle导出数据,并将其导入到postgresql中。当我尝试将数据导入到PostgreSQL的我得到这个错误:从Oracle迁移到PostgreSQL编码错误

错误:无效字节序列编码“UTF8”:0xcb 0xcf 背景:COPY项目,线路810

我发现,Oracle数据库的设置defult将被编码为ASCII,因此CSV文件通常以ASCII格式输出,在Postgres DB中默认编码为UTF-8,不允许接受ASCII

因此,在从Oracle导出数据时到CSV文件,我需要使用存储过程与UTF-8编码,我曾尝试跟随在甲骨文它不起作用。

CREATE OR REPLACE 
PROCEDURE export_main(dir VARCHAR2, file_name VARCHAR2) 
    IS 
select_stmt VARCHAR2(100) := 'SELECT MTYPE || '','' || MNO FROM MAIN'; 
    cur INTEGER; 
    file UTL_FILE.FILE_TYPE; 
    row_value VARCHAR2(4000); 
    ret INTEGER; 
    BEGIN 
    -- Open a cursor for the specified SELECT statement 
    cur := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE(cur, select_stmt, DBMS_SQL.NATIVE); 
    ret := DBMS_SQL.EXECUTE(cur); 

    -- All columns were concatenated into single value in SELECT 
    DBMS_SQL.DEFINE_COLUMN(cur, 1, row_value, 4000); 

    -- Open the file for writing 
    --file := UTL_FILE.FOPEN(UPPER(dir), file_name, 'w', 32767); 
file := UTL_FILE.FOPEN_NCHAR(UPPER(dir), file_name, 'w', 32767); 
    -- Export rows one by one 
    LOOP 
     ret := DBMS_SQL.FETCH_ROWS(cur); 
     EXIT WHEN ret = 0; 

     -- Get the value 
     row_value := NULL; 
     DBMS_SQL.COLUMN_VALUE(cur, 1, row_value); 

     -- Write the row to the file 
     -- UTL_FILE.PUT_LINE(file, row_value); 
UTL_FILE.PUT_LINE_NCHAR(file, TO_NCHAR(row_value)); 
    END LOOP; 

    UTL_FILE.FCLOSE(file); 
    DBMS_SQL.CLOSE_CURSOR(cur); 

    EXCEPTION WHEN NOT_LOGGED_ON THEN 
    DBMS_OUTPUT.PUT_LINE ('A program issues a database call without being connected to Oracle.'); 
    END; 

否则在在Postgres的数据库,我需要编码与UTF-8与存储过程 这里导入从CSV文件中的数据的时间是在Postgres的

begin 
    set schema 'public'; 
    raise notice 'CSV PATH: %,TABLE NAME: %',csv_path,target_table; 
    execute format('truncate %I ',target_table); 
    execute format('copy %I from %L WITH (FORMAT csv)',target_table, csv_path); 
    return; 
end; 

你的脚本想看到CSV文件?

回答

0

您可以使用SET client_encoding='latin1'来告诉postgres您正在发送的数据的编码。将latin1替换为oracle数据库中使用的编码。

可以找到postgres支持的字符集列表here。该列表还提到了SQL_ASCII,但是对于值0-127而不是值128-255,ASCII只是完全标准化的。所以这些更高的值不能转换为UTF8,因为它没有定义它们的含义。

+0

我需要使用script.Not由终端无论如何它不会持续一次会话或机器重新启动。它是临时的。 –

+0

这不是一个终端SET命令,它是一个postgresql SET命令。 – Eelke

+0

Eelke您能否将SET命令放在上面的脚本中 –