Saltar al contenido

Oracle: exporta una tabla con blobs a un archivo .sql que se puede importar nuevamente

Solución:

No creo que esto sea posible con SQL Developer (pero no lo uso muy a menudo).

El cliente SQL que estoy usando, SQL Workbench / J, puede hacer esto.

Hay varias formas de exportar estos datos.

Genere un script propietario

Puede crear un script SQL que use una notación especial (específica de la herramienta) para hacer referencia a un archivo externo, algo como:

INSERT INTO images
  (name, data)
VALUES
  ('foobar', {$blobfile="blob_r1_c2.data"});

La declaración anterior solo se puede ejecutar con SQL Workbench nuevamente. No es compatible con ningún otro cliente SQL.

Utilice utl_raw

Otra alternativa es utilizar un “literal de blob”, pero debido al límite de Oracle de 4000 bytes para un literal de carácter, esto solo funciona para De Verdad pequeños valores de blob:

INSERT INTO images
  (name, data)
VALUES
  ('foobar', to_blob(utl_raw.cast_to_raw('......')));

donde el carácter literal para el cast_to_raw La llamada contendría los valores hexadecimales del BLOB. Como esto requiere 2 caracteres por “byte de blob”, no puede manejar BLOB de más de 2000 bytes con eso. Pero esa sintaxis funcionaría para casi todas las herramientas SQL de Oracle (si pueden manejar scripts con líneas muy largas).

Archivo de entrada SQL * Loader

La tercera alternativa es exportar los datos a un archivo de texto que se puede importar usando SQL * Loader:

El archivo de texto contendría algo como esto:

NAME    DATA
foobar  blob_r1_c2.data

Junto con el siguiente archivo de control SQL * Loader:

OPTIONS (skip=1)
LOAD DATA CHARACTERSET 'WE8ISO8859P15'
INFILE 'images.txt'
APPEND
INTO TABLE IMAGES
FIELDS TERMINATED BY 't' TRAILING NULLCOLS
(
  NAME,
  lob_file_data FILLER,
  DATA LOBFILE(lob_file_data) TERMINATED BY EOF
)

Esto se puede cargar usando SQL * Loader y, por lo tanto, no necesita SQL Workbench para importar los datos.

Más detalles están en el manual

Editar

Como Alex ha señalado en su comentario, también puede usar una exportación de DataPump, pero eso requiere que tenga acceso al sistema de archivos en el servidor. Todas las soluciones anteriores almacenan los datos del cliente.

Gracias por tu respuesta. Usé la tercera alternativa. Primero descargué SQL Workbench / J. Luego utilicé el siguiente comando para hacer una exportación:

WbExport -type=text -file="c:tempImages" delimiter="|" -decimal="," -sourcetable=Images -formatfile=oracle;

Esto produjo un archivo Images.txt y muchos archivos Images_r * _c2.data y un archivo Images.ctl.

Entonces podría usar el siguiente comando para importar:

sqlldr [email protected]/mypassword control=Images.ctl

Si es absolutamente necesario usar un solo archivo .sql para importar el BLOB, puede generar el script usando PL / SQL:

set serveroutput on
declare
  lob_in blob;
  i integer := 0;
  lob_size integer;
  buffer_size integer := 1000;
  buffer raw(32767);
begin
  select
    data, dbms_lob.getlength(data)
    into lob_in, lob_size
  from images
  where name="example.png";

  for i in 0 .. (lob_size / buffer_size) loop
    buffer := dbms_lob.substr(lob_in, buffer_size, i * buffer_size + 1);
    dbms_output.put('dbms_lob.append(lob_out, hextoraw(''');
    dbms_output.put(rawtohex(buffer));
    dbms_output.put_line('''));');
  end loop;
end;

Su salida será el contenido del BLOB codificado como:

dbms_lob.append(lob_out, hextoraw('FFD8FFE0...0000'));
dbms_lob.append(lob_out, hextoraw('00000000...0000'));
...
dbms_lob.append(lob_out, hextoraw('007FFFD9'));

Que puede cargar en una fila ya insertada con PL / SQL:

declare
  lob_out blob;
begin
  select data into lob_out
  from images
  where name="example.png"
  for update;

  dbms_lob.append(lob_out, hextoraw('FFD8FFE0...0000'));
  dbms_lob.append(lob_out, hextoraw('00000000...0000'));
  ...
  dbms_lob.append(lob_out, hextoraw('007FFFD9'));
end;

Solo recuerde que el archivo .sql resultante será enorme.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *