我正致力于将数据从oracle数据库迁移到postgresql数据库。我遇到了一个问题,我从oracle导出数据,使用存储过程,并将其导入postgresql。当我尝试将数据导入postgresql时,我收到此错误:
错误:编码的字节序列无效" UTF8":0xcb 0xcf 背景:COPY项目,第810行
我发现defult设置的Oracle数据库将以ASCII编码,因此CSV文件通常以ASCII格式输出,而Postgres DB默认以UTF-8编码,不允许接受ASCII
因此,在将数据从Oracle导出到CSV文件时,我需要使用存储过程使用UTF-8进行编码,我确实在oracle上尝试使用,但是它没有用。
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 DB中从CSV文件导入数据时,我需要使用带存储过程的UTF-8进行编码 这是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 :(得分:0)
您可以使用SET client_encoding='latin1'
告诉postgres您正在发送的数据的编码。将latin1替换为oracle数据库中使用的编码。
可以找到postgres支持的字符集列表here。此列表还提到了SQL_ASCII,但由于ASCII仅针对值0-127而非值128-255进行了完全标准化。因此,这些较高的值无法转换为UTF8,因为它没有定义它们的含义。