ORA-22835: Buffer příliš malý a ORA-25137: Údaje hodnota mimo rozsah

0

Otázka

Jsme pomocí software, který má omezené Oracle schopnosti. Já třeba filtrovat přes CLOB pole tím, že to má konkrétní hodnotu. Normálně, mimo tento software bych udělat něco jako:

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

Nicméně, tato funkce není podporována, takže jsem se snaží využít CAST místo. Zkoušel jsem mnoho různých pokusů, ale zatím jsou to, co jsem našel:

Software má vestavěný-v dotazu checker/validator a to jsou ty, to se ukazuje jako neplatný:

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

Nicméně, validátor se přijmout tyto:

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

Bohužel, i když validátor umožňuje tyhle projít, při spuštění dotazu k načtení dat, jsem si ORA-22835: Buffer too small při použití VARCHAR nebo NVARCHAR. A já si ORA-25137: Data value out of range při použití CHAR.

Existují jiné způsoby, jak bych mohl zkusit zkontrolovat, že moje CLOB pole má určitou hodnotu při filtrování dat? Pokud ne, jak mohu opravit můj aktuální problémy?

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

Nejlepší odpověď

1

Chybové jste stále naznačuje, že Oracle se snaží aplikovat CAST(t.new_value AS VARCHAR(10)) na řádku, kde new_value má více než 10 znaků. To dává smysl, vzhledem k tomu váš popis, že new_value je obecný audit pole, které má hodnoty z velkého množství různých stolů s různými dat délky. Vzhledem k tomu, že, budete muset struktura dotazu tak, že nutí optimizer pro snížení sada řádků se ucházíte o cast do dolů jen ty, kde new_value má jen jeden znak před použitím cast.

Nevěděl, jaký rozsah software používáte poskytuje pro strukturování kódu, nejsem si jistý, jaké možnosti máte. Uvědomte si, že v závislosti na tom, jak silné ty to potřebuješ, optimalizátor má docela dost flexibilitu vybrat použít predikáty a funkce na projekci v libovolném pořadí. Takže i pokud zjistíte, že přístup, který funguje jednou, to může přestat fungovat v budoucnu, kdy statistiky změnu nebo inovaci databáze a Oracle rozhodne zvolit jiný plán.

2021-11-24 16:59:52
0

Pomocí tohoto jako ukázková data

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

Budete muset použít dbms_lob.substr(col,1) chcete získat první znak (z výchozí offset= 1)

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

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

Všimněte si, že výchozí amount (= délka) podřetězec je 32767 takže pouze pomocí DBMS_LOB.SUBSTR(COL) vrátí víc, než si očekává.

CAST pro CLOB ano ne řez řetězec na lité délka, ale (jak uvádí) vrací výjimku ORA-25137: Data value out of range pokud původní řetězec je longert, že odlita délka.

Jak je doloženo pro CAST prohlášení

OBSAZENÍ přímo nepodporuje některou z LOB datové typy. Při použití OBSAZENÍ převést hodnotu CLOB do znaková data nebo typu BLOB hodnoty do datového typu RAW, databáze implicitně převádí LOB hodnotu znaku nebo raw data a explicitně vrhá výsledné hodnoty do cílového datového typu. Pokud výsledná hodnota je větší než cílová typ databáze vrátí chybu.

2021-11-23 17:06:33

Bohužel i po přidání odsazení, dotaz validátor nezná DBMS_LOB.SUBSTR() takže nemůžu použít. Myslel jsem, že CAST je schopen snížit řetězec, protože jsme také museli použít řešení pro TRUNC: CAST(CAST(date_field AS VARCHAR(9)) AS DATE) a to funguje. To zbaví době část. Doufal jsem, že bychom mohli udělat něco podobného pro tento jeden.
Patrick Gregorio

Ano, to funguje pro VARCHAR ale bohužel ne pro CLOB Aktualizoval jsem odpověď. @PatrickGregorio
Marmite Bomber

V jiných jazycích

Tato stránka je v jiných jazycích

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