ORA-22835: Buffer troppo piccolo e ORA-25137: Dati valore fuori range

0

Domanda

Stiamo usando un software che ha limitato la funzionalità di Oracle. Ho bisogno di filtrare attraverso un campo CLOB, assicurandosi che essa ha un valore specifico. Normalmente, al di fuori di questo software, mi piacerebbe fare qualcosa di simile:

DBMS_LOB.SUBSTR(t.new_value) = 'Y'

Tuttavia, questo non è supportata, quindi sto cercando di utilizzare CAST invece. Ho provato diversi tentativi, ma finora questi sono che cosa ho trovato:

Il software dispone di un built-in query correttore/validator e questi sono quelli che mostra come non valido:

DBMS_LOB.SUBSTR(t.new_value)
CAST(t.new_value AS VARCHAR2(10))
CAST(t.new_value AS NVARCHAR2(10))

Tuttavia, il validatore non accettare queste:

CAST(t.new_value AS VARCHAR(10))
CAST(t.new_value AS NVARCHAR(10))
CAST(t.new_value AS CHAR(10))

Purtroppo, anche se il validatore consente a questi ultimi di passare attraverso, quando si esegue la query per recuperare i dati, ho ORA-22835: Buffer too small quando si utilizza VARCHAR o NVARCHAR. E ho ORA-25137: Data value out of range quando si utilizza CHAR.

Ci sono altri modi potrei provare a controllare che il mio campo CLOB ha un valore specifico quando si filtrano i dati? Se no, come posso risolvere i miei problemi attuali?

database oracle
2021-11-23 16:17:40
2

Migliore risposta

1

L'errore che stai ricevendo indica che Oracle sta cercando di applicare il CAST(t.new_value AS VARCHAR(10)) per una riga in cui new_value ha più di 10 caratteri. Che senso dato che la tua descrizione new_value è un generico controllo campo di valori da un gran numero di tavoli diversi con una varietà di lunghezze di dati. Dato che, avete bisogno di strutturare la query in modo che le forze dell'ottimizzatore per ridurre il set di righe che si sta applicando il cast fino a solo per quelle in cui new_value ha solo un singolo carattere prima di applicare il cast.

Non sapendo che tipo di portata che il software che si sta utilizzando prevede la strutturazione di codice, non sono sicuro di quali opzioni si hanno. Essere consapevoli del fatto che a seconda di come robusto avete bisogno di questo, l'ottimizzatore ha un po ' di flessibilità di scegliere di applicare predicati e funzioni di proiezione in un ordine arbitrario. Quindi, anche se si trova un approccio che funziona una volta, si potrebbe smettere di funzionare in futuro, quando le statistiche modifica o l'aggiornamento del database e Oracle decide di scegliere un piano diverso.

2021-11-24 16:59:52
0

Utilizza questo come dati di esempio

create table tab1(col clob);
insert into tab1(col) values (rpad('x',3000,'y'));

È necessario utilizzare dbms_lob.substr(col,1) per ottenere il primo carattere (dal default offset= 1)

select dbms_lob.substr(col,1) from tab1;

DBMS_LOB.SUBSTR(COL,1)
----------------------
x

Nota che i di default amount (= lunghezza della sottostringa è 32767 quindi, utilizzando solo DBMS_LOB.SUBSTR(COL) ritornerà più di quanto si aspetta.

CAST per CLOB non non tagliare la stringa per la fusione di lunghezza, ma (come si osserva) restituisce l'eccezione ORA-25137: Data value out of range se la stringa originale è longert che la fusione di lunghezza.

Come documentato per la CAST istruzione

Il CAST non supporta direttamente uno qualsiasi dei tipi di dati LOB. Quando si utilizza il CAST per la conversione di un CLOB valore in un tipo di dati carattere o un BLOB valore nel tipo di dati RAW, il database implicitamente converte il valore LOB di carattere o di dati grezzi e quindi in modo esplicito getta il valore risultante nel tipo di dati di destinazione. Se il valore risultante è maggiore il tipo di destinazione, quindi il database restituisce un errore.

2021-11-23 17:06:33

Purtroppo anche dopo l'aggiunta di offset, la query validatore non riconosce DBMS_LOB.SUBSTR() quindi non posso usare quella. Ho pensato CAST è in grado di tagliare la corda, perché abbiamo dovuto utilizzare una soluzione per TRUNC: CAST(CAST(date_field AS VARCHAR(9)) AS DATE) e funziona. Elimina la porzione di tempo. Speravo si potesse fare qualcosa di simile per questo.
Patrick Gregorio

Sì, questo funziona per VARCHAR ma purtroppo non per CLOB Ho aggiornato la risposta. @PatrickGregorio
Marmite Bomber

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................