Autor Thema: Oracle: "string literal too long" trotz Check  (Gelesen 10986 mal)

claus

  • Gast
Oracle: "string literal too long" trotz Check
« am: 04. Juli 2006, 16:55:21 »
Falls es jemanden wie mir gehen sollte, hier eine kleine Hilfe:

Man überprüft z.B. mit Perl, ob ein geänderter Wert eines Datenbanken-Felds über die dafür vorgesehene Maximalgrösse kommen würde (z.B. varchar2(4000):

my $length = length($new_value);
if ($length < 4000)
                {
                        &update_component_table($new_value, $id);
                }
                else
                {
                        print "[ERROR] component $id value would be too long!\n";
                }

Perl gibt zurück, dass alles innerhalb der Toleranzen ist (also kleiner als 4000 Zeichen), aber Oracle meldet sich dann mit der "ORA-01704" Fehlermeldung (String Literal too long), dann hat das normalerweise den Grund, dass Oracle als NLS_LENGTH_SEMANTICS(*) eben Byte hat und nicht Chars, was der einfache Perl Code lediglich abprüft.

Um das zu vermeiden, muss man folgendes hinzufügen:

(... my $length = length($new_value);... )
foreach (split (//, $new_value))
{
      $length++ if (ord($_) > 127);
}
(...if ($length < 4000)...)

Damit wird man, wie ich (wir) heute feststellen, dass die Länge des Strings eben doch grösser als 4000 Bytes (und eben weniger als 4000 Zeichen) ist.


(*) = Diese Attribute findet man über:

select * from v$nls_parameters
Im "Oracle Programming Book" steht dazu übrigens nur "Contact your Database Administrator" anstelle, dass eben dieser einzeilige SQL-Befehl angegeben wird... Mann oh Mann.

Vielleicht hilft es jemanden, hat mich heute eine gute Stunde oder so beschäftigt

Claus

sonnenblen.de - Das unabhängige Sun User Forum

Oracle: "string literal too long" trotz Check
« am: 04. Juli 2006, 16:55:21 »

Offline sunfreak

  • Sobl Bachelor
  • ***
  • Beiträge: 113
Re: Oracle: "string literal too long" trotz Check
« Antwort #1 am: 22. September 2006, 13:57:12 »
Jou,

da bin ich auch schon mal reingerasselt. Je nach Zeichesatz braucht Oracle 3 byte um einen Chaqracter abzuspeichern.
Früher mit 7Byte Zeichensatz war das wurscht.
Eigentlich muesste man den Datentyp von VARCHAR2 in VARBYTE2 umtaufen ;-)
(Was von der Definition des Datentyps byte her auch wieder schlecht ist).

Allerdings habe ich noch keine richtige Berechnungsmöglichkeit gefunden
wieviel Byte denn, abhängig vom Characterset, nun für die Entsprechende
Eingabe benötigt werden.

Frank

claus

  • Gast
Re: Oracle: "string literal too long" trotz Check
« Antwort #2 am: 04. Oktober 2006, 20:17:05 »
Da kann ich denke ich Abhilfe schaffen (hat bei meinem vorigen Arbeitgeber zumindest funktioniert):

(... my $length = length($new_value);... )
foreach (split (//, $new_value))
{
      $length++ if (ord($_) > 127);
      $length++ if (ord($_) > 255);
}

Also, ein Byte, für 0 < x < 127, zwei Byte für 128 < x < 255 und drei Byte für x > 255.

Das ist aber nur von Bedeutung, wenn für  NLS_LENGTH_SEMANTICS "Byte" als Wert gesetzt ist.

Zitat
ord

    Returns the numeric (the native 8-bit encoding, like ASCII or EBCDIC, or Unicode) value of the first character of EXPR. If EXPR is omitted, uses $_.

    For the reverse, see chr. See the perlunicode manpage and the encoding manpage for more about Unicode.

(Quelle: http://www.mathematik.uni-ulm.de/help/perl5/doc/perlfunc.html#item_ord)



Claus
« Letzte Änderung: 04. Oktober 2006, 20:26:56 von claus »