Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

EKSPOR SEBAGAI PERNYATAAN MASUKKAN:Tetapi dalam SQL Plus, baris menimpa 2500 karakter!

Wow, kendala itu cukup membatasi tapi saya pikir mungkin ada jalan keluarnya. Saya pikir Anda mungkin harus menulis skrip kecil Anda sendiri untuk ini.

Saya akan menggunakan Java dengan JDBC sendiri (tetapi bahasa apa pun yang dapat terhubung ke dan membaca database, dan string keluaran, akan berhasil), menulis sebuah program kecil yang mengambil satu set catatan dari setiap baris dalam database. Kemudian, untuk setiap baris tersebut:

  • Buat pernyataan insert dengan data lengkap. Jika ini kurang dari 2.000 byte, maka keluarkan saja ke file dan lanjutkan ke baris berikutnya.

  • Jika tidak, buat pernyataan sisipkan untuk setiap bidang, tetapi biarkan c13 bidang sebagai '' (kosong).

  • Kemudian, selama c13input . Anda string lebih besar dari 2000 karakter, output pernyataan pembaruan dalam bentuk "update tbl set c13 = c13 || '" + c13input.substring (0,2000) + "' where ..." (tambahkan 2000 karakter berikutnya) dan kemudian lakukan c13input = c13input.substring(2000) untuk menghapus karakter tersebut dari string Anda.

  • Sekali c13input panjangnya kurang dari atau sama dengan 2000 karakter, cukup keluarkan satu pembaruan terakhir untuk memasangnya di akhir.

Ini memungkinkan Anda untuk menyimpan pernyataan SQL individual Anda di sekitar tanda 2000 karakter dan secara efisien menjalankan SQL yang benar untuk mengisi kembali tabel database lain.

Ini adalah jenis hal yang saya bicarakan (untuk tabel yang hanya berisi kunci utama c1 dan varchar honkin' besar c13 ):

rowset r = db.exec ("select * from oldtable");
while r.next != NO_MORE_ROWS:
    string s = "insert into newtable (c1,c13) values ('" +
        r.get("c1") + "','" + r.get("c13") + "')"
    if s.len() < 2000:
        print s
    else:
        s = "insert into newtable (c1,c13) values ('" + r.get("c1") + "','')"
        print s
        f = r.get("c13")
        while f.len() > 2000:
            s = "update newtable set c13 = c13 || '" + f.substring(0,2000) + ')"
            f = f.substring(2000)
            print s
        endwhile
        s = "update newtable set c13 = c13 || '" + f + ')"
        print s
    endif
endwhile

Jelas, Anda mungkin perlu mengubah string untuk memungkinkan penyisipan karakter khusus - Saya tidak yakin format apa yang diharapkan Oracle ini, tetapi mudah-mudahan akan menjadi masalah sederhana untuk meneruskan string (r.get("c13") jika panjang sisipan penuh kurang dari 2000, f.substring(0,2000) dan f jika Anda juga membuat pembaruan) ke fungsi pembantu untuk melakukan ini.

Jika morphing itu kemungkinan akan meningkatkan ukuran garis yang dicetak, Anda mungkin ingin menurunkan ambang batas kembali ke 1000 agar aman, untuk memastikan string yang diubah tidak menghasilkan garis yang lebih besar dari batas PL/SQL.

Maaf jika itu tampak berbelit-belit tetapi batasan yang Anda nyatakan membuat kami sedikit lumpuh. Mungkin ada cara yang lebih baik tetapi saya tidak bisa memikirkan cara yang memenuhi semua kriteria Anda.

Pembaruan: Tampaknya Anda bahkan lebih lumpuh dari yang diperkirakan semula:jika Anda harus membatasi diri Anda pada SQL untuk menghasilkan scriptnya juga cara menjalankannya, ada caranya, walaupun menyiksa.

Anda dapat menggunakan SQL untuk menghasilkan SQL. Menggunakan tabel saya yang disebutkan sebelumnya dengan c1 dan c13 , Anda dapat melakukan:

select
    'insert into newtable (c1,c13) values ("' ||
    c1 ||
    '","");'
from oldtable;
# Xlates to: insert into newtable (c1,c13) values ("[c1]","");

Itu akan memberi Anda semua insert dasar Anda pernyataan untuk menduplikasi semuanya kecuali c13 kolom.

Yang perlu Anda lakukan adalah membuat lebih banyak pernyataan untuk menyetel c13 . Untuk memperbarui c13 untuk semua nilai dengan panjang 1000 atau kurang (set sederhana):

select
    'update newtable set c13 = "' ||
    c13 ||
    '" where c1 = "' ||
    c1 ||
    '";'
from oldtable where length(c13) <= 1000;
# Xlates to: update newtable set c13 = "[c13]" where c1 = "[c1]";
#   but only for rows where length([c13]) <= 1000

Kemudian, untuk update c13 untuk semua nilai antara 1001 dan 2000 karakter (setel lalu tambahkan):

select
    'update newtable set c13 = "' ||
    substring(c13,1,1000) ||
    '" where c1 = "' ||
    c1 ||
    '";'
from oldtable where length(c13) > 1000 and length(c13) <= 2000;
select
    'update newtable set c13 = c13 || "' ||
    substring(c13,1001,1000) ||
    '" where c1 = "' ||
    c1 ||
    '";'
from oldtable where length(c13) > 1000 and length(c13) <= 2000;
# Xlates to: update newtable set c13 =        "[c13a]" where c1 = "[c1]";
#            update newtable set c13 = c13 || "[c13b]" where c1 = "[c1]";
#   but only for rows where length([c13]) > 1000 and <= 2000
#   and [c13a]/[c13b] are the first/second thousand chars of c13.

Dan seterusnya untuk yang panjangnya 2001-ke-3000 dan 3001-ke-4000.

Kemungkinan akan ada beberapa penyesuaian yang dilakukan. Saya senang memberi Anda cara untuk menyelesaikannya, tetapi keinginan saya untuk mengerjakan hal mengerikan seperti itu hingga selesai sangat minim :-)

Apakah itu akan menyelesaikan pekerjaan? Ya. Apakah itu cantik? Saya akan mengatakan bahwa itu adalah "TIDAK!" tetapi, mengingat kendala Anda, itu mungkin yang terbaik yang dapat Anda harapkan.

Sebagai bukti konsep, inilah skrip SQL di DB2 (tidak ada fitur khusus, ini akan berfungsi dengan baik di DBMS apa pun yang memiliki length dan substr setara):

# Create table and populate.

DROP TABLE XYZ;
COMMIT;
CREATE TABLE XYZ (F1 VARCHAR(1),F2 VARCHAR(20));
COMMIT;
INSERT INTO XYZ VALUES ('1','PAX');
INSERT INTO XYZ VALUES ('2','GEORGE');
INSERT INTO XYZ VALUES ('3','VLADIMIR');
INSERT INTO XYZ VALUES ('4','ALEXANDRETTA');
SELECT * FROM XYZ ORDER BY F1;

# Create initial insert statem,ents.

SELECT 'INSERT INTO XYZ (F1,F2) VALUES (' || F1 ','''');' 
    FROM XYZ;

# Updates for 1-5 character F2 fields.

SELECT 'UPDATE XYZ SET F2 = ''' || F2 ||
    ''' WHERE F1 = ''' || F1 || ''';'
    FROM XYZ WHERE LENGTH(F2) <= 5;

# Updates for 6-10 character F2 fields.

SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
    ''' WHERE F1 = ''' || F1 || ''';'
    FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;

SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6) ||
    ''' WHERE F1 = ''' || F1 || ''';'
    FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;

# Updates for 11-15 character F2 fields.

SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
    ''' WHERE F1 = ''' || F1 || ''';'
    FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;

SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6,5) ||
    ''' WHERE F1 = ''' || F1 || ''';'
  FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;

SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,11) || 
    ''' WHERE F1 = ''' || F1 || ''';'
    FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;

dan ini menghasilkan baris berikut:

> DROP TABLE XYZ;
> COMMIT;
> CREATE TABLE XYZ (F1 VARCHAR(1),F2 VARCHAR(20));
> COMMIT;
> INSERT INTO XYZ VALUES ('1','PAX');
> INSERT INTO XYZ VALUES ('2','GEORGE');
> INSERT INTO XYZ VALUES ('3','VLADIMIR');
> INSERT INTO XYZ VALUES ('4','ALEXANDRETTA');
> SELECT * FROM XYZ;
    F1  F2
    --  ------------
    1   PAX
    2   GEORGE
    3   VLADIMIR
    4   ALEXANDRETTA

> SELECT 'INSERT INTO XYZ (F1,F2) VALUES (' || F1 || ','''');'
> FROM XYZ;
    INSERT INTO XYZ (F1,F2) VALUES (1,'');
    INSERT INTO XYZ (F1,F2) VALUES (2,'');
    INSERT INTO XYZ (F1,F2) VALUES (3,'');
    INSERT INTO XYZ (F1,F2) VALUES (4,'');

> SELECT 'UPDATE XYZ SET F2 = ''' || F2 ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) <= 5;
    UPDATE XYZ SET F2 = 'PAX' WHERE F1 = '1';

> SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
    UPDATE XYZ SET F2 = 'GEORG' WHERE F1 = '2';
    UPDATE XYZ SET F2 = 'VLADI' WHERE F1 = '3';

> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
    UPDATE XYZ SET F2 = F2 || 'E' WHERE F1 = '2';
    UPDATE XYZ SET F2 = F2 || 'MIR' WHERE F1 = '3';

> SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
    UPDATE XYZ SET F2 = 'ALEXA' WHERE F1 = '4';

> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
    UPDATE XYZ SET F2 = F2 || 'NDRET' WHERE F1 = '4';

> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,11) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
    UPDATE XYZ SET F2 = F2 || 'TA' WHERE F1 = '4';

Memecah garis output, kita mendapatkan:

INSERT INTO XYZ (F1,F2) VALUES (1,'');
INSERT INTO XYZ (F1,F2) VALUES (2,'');
INSERT INTO XYZ (F1,F2) VALUES (3,'');
INSERT INTO XYZ (F1,F2) VALUES (4,'');
UPDATE XYZ SET F2 = 'PAX' WHERE F1 = '1';
UPDATE XYZ SET F2 = 'GEORG' WHERE F1 = '2';
UPDATE XYZ SET F2 = 'VLADI' WHERE F1 = '3';
UPDATE XYZ SET F2 = F2 || 'E' WHERE F1 = '2';
UPDATE XYZ SET F2 = F2 || 'MIR' WHERE F1 = '3';
UPDATE XYZ SET F2 = 'ALEXA' WHERE F1 = '4';
UPDATE XYZ SET F2 = F2 || 'NDRET' WHERE F1 = '4';
UPDATE XYZ SET F2 = F2 || 'TA' WHERE F1 = '4';

yang seharusnya memberi Anda baris asli, meskipun secara tidak langsung.

Dan itu adalah upaya sebanyak yang saya bisa lakukan untuk satu pertanyaan tanpa otak saya menggoreng, jadi saya akan mengucapkan selamat tinggal kepada Anda kecuali jika ada kesalahan serius yang ditunjukkan kepada saya.

Semoga berhasil dengan proyek Anda, dan semoga sukses.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menggabungkan cx_Oracle dengan Pyinstaller

  2. Bagaimana cara memanggil Prosedur Tersimpan di dalam paket Oracle dengan Entity Framework?

  3. Bagaimana Melewati Daftar Objek Java ke Oracle Stored Procedure Menggunakan MyBatis?

  4. ORACLE Cara menggunakan spool dengan lokasi spool dinamis

  5. Contoh Fungsi Oracle (Nomor Pengembalian)