oracle - primary - sqlplus column nowrap
SELECCIONE DISTINCT CLOB_COLUMN FROM TABLE; (5)
Si es aceptable truncar su campo a 32767 caracteres, esto funciona:
select distinct dbms_lob.substr(FIELD_CLOB,32767) from Table1
Me gustaría encontrar los distintos valores CLOB que pueden asumir la columna llamada CLOB_COLUMN (de tipo CLOB) contenida en la tabla denominada COPIA.
He seleccionado una FORMA PROCEDIMENTAL para resolver este problema, pero preferiría dar un SELECCIONAMIENTO simple como el siguiente: SELECCIONAR DISTINCT CLOB_COLUMN FROM TABLE evitando el error "ORA-00932: tipos de datos incoherentes: esperado - obtuvo CLOB"
¿Cómo puedo conseguir esto?
Gracias de antemano por su amable cooperación. Esta es la forma de proceder que he pensado:
-- Find the distinct CLOB values that can assume the column called CLOB_COLUMN (of type CLOB)
-- contained in the table called COPIA
-- Before the execution of the following PL/SQL script, the CLOB values (including duplicates)
-- are contained in the source table, called S1
-- At the end of the excecution of the PL/SQL script, the distinct values of the column called CLOB_COLUMN
-- can be find in the target table called S2
BEGIN
EXECUTE IMMEDIATE ''TRUNCATE TABLE S1 DROP STORAGE'';
EXECUTE IMMEDIATE ''DROP TABLE S1 CASCADE CONSTRAINTS PURGE'';
EXCEPTION
WHEN OTHERS
THEN
BEGIN
NULL;
END;
END;
BEGIN
EXECUTE IMMEDIATE ''TRUNCATE TABLE S2 DROP STORAGE'';
EXECUTE IMMEDIATE ''DROP TABLE S2 CASCADE CONSTRAINTS PURGE'';
EXCEPTION
WHEN OTHERS
THEN
BEGIN
NULL;
END;
END;
CREATE GLOBAL TEMPORARY TABLE S1
ON COMMIT PRESERVE ROWS
AS
SELECT CLOB_COLUMN FROM COPIA;
CREATE GLOBAL TEMPORARY TABLE S2
ON COMMIT PRESERVE ROWS
AS
SELECT *
FROM S1
WHERE 3 = 9;
BEGIN
DECLARE
CONTEGGIO NUMBER;
CURSOR C1
IS
SELECT CLOB_COLUMN FROM S1;
C1_REC C1%ROWTYPE;
BEGIN
FOR C1_REC IN C1
LOOP
-- How many records, in S2 table, are equal to c1_rec.clob_column?
SELECT COUNT (*)
INTO CONTEGGIO
FROM S2 BETA
WHERE DBMS_LOB.
COMPARE (BETA.CLOB_COLUMN,
C1_REC.CLOB_COLUMN) = 0;
-- If it does not exist, in S2, a record equal to c1_rec.clob_column,
-- insert c1_rec.clob_column in the table called S2
IF CONTEGGIO = 0
THEN
BEGIN
INSERT INTO S2
VALUES (C1_REC.CLOB_COLUMN);
COMMIT;
END;
END IF;
END LOOP;
END;
END;
Podría comparar los valores hash del CLOB para determinar si son diferentes:
SELECT your_clob
FROM your_table
WHERE ROWID IN (SELECT MIN(ROWID)
FROM your_table
GROUP BY dbms_crypto.HASH(your_clob, dbms_crypto.HASH_SH1))
Editar:
La función HASH
no garantiza que no haya colisión. Sin embargo, por diseño, es muy poco probable que tenga una colisión. Aún así, si el riesgo de colisión (<2 ^ 80?) No es aceptable, puede mejorar la consulta comparando (con dbms_lob.compare
) el subconjunto de filas que tienen los mismos valores hash.
Utiliza este enfoque En el contenido de la columna del perfil de la tabla , se encuentra NCLOB. Agregué la cláusula where para reducir el tiempo de ejecución que es alto,
with
r as (select rownum i, content from profile where package = ''intl''),
s as (select distinct (select min(i) from r where dbms_lob.compare(r.content, t.content) = 0) min_i from profile t where t.package = ''intl'')
select (select content from r where r.i = s.min_i) content from s
;
No se trata de ganar premios por eficiencia, sino que debería funcionar.
Para omitir el error de oráculo, debe hacer algo como esto:
SELECCIONE CLOB_COLUMN DESDE LA TABLA COPIA C1 DONDE SE ENCUENTRA C1.ID (SELECCIONE DISTINCT C2.ID DESDE COPIA C2 DONDE ...)
seleccione distinct DBMS_LOB.substr (column_name, 3000) from table_name;