Postgres 9.1にdbがあります。 dbは、byteaファイルに格納されているいくつかのバイナリデータを収集しました。 Oracle 10gにデータをコピーする必要があります。どうやってするの?
Postgres9.1にplines
というテーブルがあります。 plines
にはbytea
フィールドshape
が含まれます。
レコード数は約500.000です。
Oracle10gにolines
というテーブルがあります。 olines
にはblob
フィールドshape
が含まれます。
plines.shape
からolines.shape
にデータをコピーする必要があります。
Postgresからbytea
データを含むテーブルをblob
を含む同様のOracleテーブルに取得する一般的な方法を次に示します。
テストを実際のテーブルに適応させるのは簡単です。おそらく、出力を読みやすくするために使用した「チャンク」のサイズを、20から文字列リテラルの2000の制限(4000/2)に増やす必要があります。各バイトは2バイトの16進数なので)。
1)postgres
テストベッド:
begin;
set role dba;
create role stack;
grant stack to dba;
create schema authorization stack;
set role stack;
--
create function random_bytea(p_length in integer)
returns bytea language plpgsql set search_path to 'stack' as $$
declare
o bytea := '';
begin
for i in 1..p_length loop
o := o||decode(lpad(to_hex(width_bucket(random(), 0, 1, 256)-1),2,'0'), 'hex');
end loop;
return o;
end;$$;
--
create function bytea_to_Oracle_sql(p_id in integer, p_data in bytea)
returns text language plpgsql set search_path to 'stack' as $$
declare
o text := 'insert into foo(id, bar) values('||p_id||', empty_blob());';
begin
for i in 0..(length(p_data)-1)/20 loop
o := o||chr(10)||'update foo set bar=append_to_blob(bar,'''
||encode(substr(p_data,i*20+1,20),'hex')||''') where id='||p_id||';';
end loop;
return o;
end;$$;
--
create table foo(id serial, bar bytea);
テストデータを挿入し、ハッシュを確認します。
insert into foo(bar) values(random_bytea(90));
insert into foo(bar) values(random_bytea(90));
select id, md5(bar) from foo;
/*
id | md5
----+----------------------------------
1 | 32a24c8827047eff517e8a40bf3ad8b4
2 | 25ac852000889ab782ad6437accf1546
*/
oracleスクリプトを生成します。
\o '/tmp/Oracle.sql'
select bytea_to_Oracle_sql(id, bar) from foo;
\o
/tmp/Oracle.sqlの内容:
insert into foo(id, bar) values(1, empty_blob());
update foo set bar=append_to_blob(bar,'ddbe858f7905551862507ddaa3b5410cba8013d4') where id=1;
update foo set bar=append_to_blob(bar,'089d6e66f16b10ba1204a4efc22a7f3c2fd45492') where id=1;
update foo set bar=append_to_blob(bar,'24d26dc887afd4412fe8163786859e77f0af3202') where id=1;
update foo set bar=append_to_blob(bar,'b3d7f2750172b2314606c36bd8313360e008a20f') where id=1;
update foo set bar=append_to_blob(bar,'f0b847763de6ee2e9521') where id=1;
insert into foo(id, bar) values(2, empty_blob());
update foo set bar=append_to_blob(bar,'3148f823befa95712bdc77ef4750207bb0018352') where id=2;
update foo set bar=append_to_blob(bar,'10730b58ea483ed876d4faa81df3ccdbed624d18') where id=2;
update foo set bar=append_to_blob(bar,'3ec40886142901c52a85173bf92393e36bd2bce2') where id=2;
update foo set bar=append_to_blob(bar,'a6b68ac3a9569f97b8ecaff7b1b87dc6e17f8b0b') where id=2;
update foo set bar=append_to_blob(bar,'04a347fdc6dae132ad9d') where id=2;
テストベッドを削除します。
rollback;
2)Oracleテストベッド:
create table foo(id integer, bar blob);
--
create or replace
function append_to_blob(p_data in blob, p_append_hex in varchar) return blob is
o blob;
begin
dbms_lob.createtemporary(o, TRUE);
dbms_lob.append(o, p_data);
dbms_lob.writeappend(o, length(p_append_hex)/2, hextoraw(p_append_hex));
return o;
end;
/
スクリプトを実行:
insert into foo(id, bar) values(1, empty_blob());
update foo set bar=append_to_blob(bar,'ddbe858f7905551862507ddaa3b5410cba8013d4') where id=1
...
ハッシュをチェック:
select id, dbms_crypto.hash(bar,2) from foo;
/*
ID DBMS_CRYPTO.HASH(BAR,2)
--- --------------------------------
1 32A24C8827047EFF517E8A40BF3AD8B4
2 25AC852000889AB782AD6437ACCF1546
*/
彼の concat_blob 関数のVincent Malgratの功績を認めました。ランダムbytea関数自体については here を参照してください