ORA-22835: Zbyt mały bufor i ORA-25137: Wartość danych wykracza poza zakres

0

Pytanie

Wykorzystujemy oprogramowanie niepełnosprawnych Oracle. Muszę filtrować polu CLOB, upewniając się, że ma pewną wartość. Zwykle, poza tym oprogramowania, bym zrobił coś takiego:

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

To jednak nie jest obsługiwany, więc staram się używać CAST zamiast. Próbowałem wiele różnych prób, ale do tej pory to jest to, co znalazłem:

Oprogramowanie ma wbudowane sprawdzanie/weryfikator wniosków, i to te, które pokazuje, jak nieprawidłowe:

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

Jednak weryfikator bierze te:

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

Niestety, nawet pomimo faktu, że validator pomija te dane, po uruchomieniu kwerendy do pobierania danych otrzymuję ORA-22835: Buffer too small podczas korzystania z VARCHAR lub NVARCHAR. I mam ORA-25137: Data value out of range podczas korzystania z CHAR.

Czy istnieją inne sposoby, którymi mógłbym spróbować sprawdzić, że moje pole CLOB ma pewne znaczenie w przypadku filtrowania danych? Jeśli nie, to jak mogę naprawić moje obecne problemy?

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

Najlepsza odpowiedź

1

Błąd, który otrzymasz, wskazuje na to, że Oracle stara się zastosować CAST(t.new_value AS VARCHAR(10)) w rzędzie, gdzie new_value zawiera więcej niż 10 znaków. To ma sens, biorąc pod uwagę twój opis, że new_value to uniwersalne pole audytu, zawierającą wartości z dużej liczby różnych tabel z różnej długości danych. Biorąc to pod uwagę, trzeba będzie uporządkować wniosku w taki sposób, aby optymalizator zmniejszał zestaw wierszy, które stosuje się cast aż do tych, gdzie new_value ma tylko jeden znak przed zastosowaniem cast.

Nie wiedząc, jaki zakres oprogramowania, którego używasz, zapewnia strukturyzacji kodu, nie jestem pewien, jakie masz opcje. Należy pamiętać, że w zależności od tego, na ile jest to konieczne, optymalizator posiada wystarczającą elastyczność zastosowania predykatów i funkcji do projekcji w kolejności losowej. Dlatego, nawet jeśli znajdziesz podejście, który zadziała jeden raz, to może przestać działać w przyszłości, gdy statystyka się zmieni lub baza danych zostanie zaktualizowana i Oracle zdecyduje się wybrać inny plan.

2021-11-24 16:59:52
0

Wykorzystując to jako przykład danych

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

Trzeba użyć dbms_lob.substr(col,1) aby uzyskać pierwszy symbol (domyślnie offset= 1)

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

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

Zwróć uwagę, że domyślnie amount (= długość podciągu jest równa 32767 dlatego należy używać tylko DBMS_LOB.SUBSTR(COL) wróci więcej, niż można się spodziewać.

CAST dla CLOB nie przycina wiersz do podanej długości, ale (jak można zauważyć) zwraca wyjątek ORA-25137: Data value out of range jeśli oryginalny ciąg dłuższy niż bieżąca długość.

Jak udokumentowane dlaCAST oświadczenie

CAST bezpośrednio nie obsługuje żaden z typów danych LOB. Podczas korzystania z DOPROWADZENIA do konwersji wartości CLOB w znakowy typ danych lub wartości dużego obiektu binarnego w SUCHY typ danych baza danych niejawnie konwertuje wartość LOB w znakowe lub surowe dane, a następnie wyraźnie konwertuje otrzymaną wartość w docelowy typ danych. Jeżeli wartość wynikowa więcej docelowego typu, baza danych zwraca błąd.

2021-11-23 17:06:33

Niestety, nawet po dodaniu przesunięcia validator zapytań nie rozpoznaje DBMS_LOB.SUBSTR() tak, że nie mogę z tego skorzystać. Myślałem CAST jest w stanie przyciąć pasek, bo nam też musiałem użyć obejście TRUNC: CAST(CAST(date_field AS VARCHAR(9)) AS DATE) i to działa. Eliminuje to część czasu. Miałem nadzieję, że będziemy mogli zrobić coś podobnego do tego.
Patrick Gregorio

Tak to działa dla VARCHAR ale, niestety, nie dla CLOB Zaktualizowałem odpowiedź. @Патрикгрегорио
Marmite Bomber

W innych językach

Ta strona jest w innych językach

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