it-swarm.com.de

ORA-01461: Kann einen LONG-Wert nur für das Einfügen in eine LONG-Spalte binden - Tritt beim Abfragen auf

Wenn ich versuche, Objekte abzufragen, bekomme ich folgenden Fehler:

ORA-01461: can bind a LONG value only for insert into a LONG column

Könnte mir bitte jemand bei der Ursache und Lösung des Problems helfen?

53
Rupesh

Ok, da Sie keinen Code gezeigt haben, mache ich hier einige Annahmen.

Basierend auf dem ORA-1461-Fehler scheint es, als hätten Sie in einer select-Anweisung einen LONG-Datentyp angegeben. Und Sie versuchen, es an eine Ausgabevariable zu binden? Ist das richtig? Der Fehler ist ziemlich einfach. Sie können einen LONG-Wert nur für das Einfügen in die LONG-Spalte binden.

Nicht sicher, was ich sonst noch sagen soll. Der Fehler ist ziemlich selbsterklärend.

Im Allgemeinen ist es eine gute Idee, vom LONG-Datentyp zu einem CLOB zu wechseln. CLOBs werden wesentlich besser unterstützt, und LONG-Datentypen sind wirklich nur aus Gründen der Abwärtskompatibilität vorhanden.

Hier ist eine Liste der LONG-Datentypeinschränkungen

Hoffentlich hilft das.

14
Mark J. Bobak

Es kann auch bei varchar2-Spalten vorkommen. Dies ist mit PreparedStatements über JDBC einfach reproduzierbar

  1. erstellen einer Tabelle mit einer Spalte von Varchar2 (20 oder einer beliebigen Länge) und
  2. einfügen in die obige Tabelle mit einer Zeile mit mehr als 20 Zeichen

Wie oben gesagt, kann es bei Typen falsch sein oder die Spaltenbreite überschritten.

Beachten Sie auch, dass, wenn varchar2 max. 4k Zeichen zulässt, die tatsächliche Grenze 2k für Doppelbytezeichen beträgt

Hoffe das hilft

162
Kiran

Dieser Fehler tritt auf, wenn versucht wird, eine Varchar-Variable zu verwenden, die länger als 4000 Byte in einer SQL-Anweisung ist. PL/SQL erlaubt Varchars mit bis zu 32767 Bytes, aber die Grenze für Datenbanktabellen und SQL-Sprachen liegt bei 4000. Sie können keine PL/SQL-Variablen verwenden, die SQL in SQL-Anweisungen nicht erkennt. Eine Ausnahme ist, wie die Nachricht erklärt, eine direkte Einfügung in eine lange Spalte.

create table test (v varchar2(10), c clob);


declare
  shortStr varchar2(10) := '0123456789';
  longStr1 varchar2(10000) := shortStr;
  longStr2 varchar2(10000);
begin
  for i in 1 .. 10000
  loop
    longStr2 := longStr2 || 'X';
  end loop;

  -- The following results in ORA-01461
  insert into test(v, c) values(longStr2, longStr2);

  -- This is OK; the actual length matters, not the declared one
  insert into test(v, c) values(longStr1, longStr1);

  -- This works, too (a direct insert into a clob column)
  insert into test(v, c) values(shortStr, longStr2);

  -- ORA-01461 again: You can't use longStr2 in an SQL function!
  insert into test(v, c) values(shortStr, substr(longStr2, 1, 4000));
end;
32
Tomasz Żuk

Ein Kollege von mir und ich fanden Folgendes heraus:

Wenn wir den Microsoft .NET Oracle-Treiber verwenden, um eine Verbindung zu einer Oracle-Datenbank herzustellen (System.Data.OracleClient.OracleConnection)

Wir versuchen, eine Zeichenfolge mit einer Länge zwischen 2000 und 4000 Zeichen in ein CLOB- oder NCLOB-Feld mit einem Datenbankparameter einzufügen

oraCommand.CommandText = "INSERT INTO MY_TABLE (NCLOB_COLUMN) VALUES (:PARAMETER1)";
// Add string-parameters with different lengths
// oraCommand.Parameters.Add("PARAMETER1", new string(' ', 1900)); // ok
oraCommand.Parameters.Add("PARAMETER1", new string(' ', 2500));  // Exception
//oraCommand.Parameters.Add("PARAMETER1", new string(' ', 4100)); // ok
oraCommand.ExecuteNonQuery();
  • eine Zeichenfolge mit einer Länge unter 2000 Zeichen löst diese Ausnahme nicht aus
  • eine Zeichenfolge mit einer Länge von mehr als 4000 Zeichen löst diese Ausnahme nicht aus
  • nur Zeichenfolgen mit einer Länge zwischen 2000 und 4000 Zeichen lösen diese Ausnahme aus

Wir haben vor vielen Jahren ein Ticket für diesen Bug bei Microsoft eröffnet, das aber immer noch nicht behoben wurde.

7
Markus1980Wien

Ich stand vor demselben Problem und löste es, indem ich einfach VARCHAR durch CLOB..__ ersetzte. Dieses link hat mir geholfen.

4
aneela

Anwendungen, die JDBC 10.1 verwenden, haben einen Fehler (Dok.-ID 370438.1) und können bei der Arbeit mit der UTF8-Zeichensatzdatenbank dieselbe ORA-01461-Ausnahme auslösen, auch wenn eingefügte Zeichen die maximale Spaltengröße überschreiten.

Empfohlene Lösung: - Verwenden Sie in diesem Fall 10gR2-JDBC-Treiber oder höher.

HTH

3
pahariayogi

Dieser ORA-01461 tritt nur beim Einfügen in eine lange Spalte auf. Dieser Fehler kann auftreten, wenn eine lange Zeichenfolge für das Einfügen in eine VARCHAR2-Spalte gebunden wird, und dies tritt meistens auf, wenn ein Zeichen mit mehreren Bytes vorhanden ist (bedeutet, dass ein Zeichen in Oracle mehr als einen Byte-Speicherplatz beanspruchen kann).

Wenn es sich bei der Datenbank um UTF-8 handelt, kann jedes Zeichen aufgrund der Tatsache, dass jedes Zeichen bis zu 3 Bytes aufnehmen kann, die Umwandlung von 3 zur Überprüfung angewendet werden und ist daher auf die Verwendung von 1333 Zeichen zum Einfügen in varchar2 (4000) beschränkt.

Eine andere Lösung wäre, den Datentyp von varchar2 (4000) in CLOB zu ändern. 

2
Murali

Die Antwort von Kiran ist definitiv die Antwort für meinen Fall.

Im Codeteil teile ich den String in 4000 Zeichenketten auf und versuche, sie in db einzufügen.

Explodiert mit diesem Fehler.

Die Fehlerursache liegt in der Verwendung von Utf-Zeichen, die jeweils 2 Byte zählen. Auch wenn ich 4000 Zeichen im Code abschneide (etw. Wie String.Take (4000)), berücksichtigt Oracle 4001, wenn der String "ö" oder ein beliebiges anderes Zeichen enthält (Non-ASCII-Zeichen) utf8) Zeichen.

2
mkb

In meinem speziellen Fall habe ich versucht, eine Base64-codierte Datei in einem BLOB-Tabellenfeld mit Mybatis zu speichern.

In meiner XML hatte ich also:

<insert id="save..." parameterType="...DTO">
    <selectKey keyProperty="id" resultType="long" order="BEFORE">
        SELECT SEQ.nextVal FROM DUAL
    </selectKey>
    insert into MYTABLE(
        ID,
        ...,
        PDF
    ) values (
        #{id, jdbcType=VARCHAR},
        ...,
        #{tcPdf, jdbcType=BLOB},
    )
</insert>

und in meinem DTO:

String getPdf(){
    return pdf;
}

Dies macht Mybatis zu einer Bedrohung, als wäre es eine String-Zeichenfolge und versucht, diese als Varchar zu speichern. Meine Lösung war also die folgende:

In meinem DTO:

Byte[] getPdf(){
    return pdf.getBytes();
}

Und hat gearbeitet.

Ich hoffe, das kann jedem helfen.

1
Francisco M

Ich hatte das gleiche Problem mit der Entity Framework-Datenbank zuerst in allen CLOB-Spalten. 

Um dieses Problem zu umgehen, habe ich die Textwerte mit Leerzeichen gefüllt, um bei Einfügevorgängen eine Breite von mindestens 4000 zu haben (ohne bessere Lösung).

1
Martin Staufcik

Ich hatte das gleiche Problem bei der Verwendung von PHP und bereitete Anweisungen für eine VARCHAR2-Spalte vor . Mein String überschritt nicht die VARCHAR2-Größe. Das Problem war, dass ich als Bindungslänge -1 verwendet habe, der Inhalt der Variablen jedoch später geändert wurde.

Zum Beispiel:

$sMyVariable = '';
$rParsedQuery = oci_parse($rLink, 'INSERT INTO MyTable (MyVarChar2Column) VALUES (:MYPLACEHOLDER)');
oci_bind_by_name($rParsedQuery, ':MYPLACEHOLDER', $sMyVariable, -1, SQLT_CHR);

$sMyVariable = 'a';
oci_execute($rParsedQuery, OCI_DEFAULT);
$sMyVariable = 'b';
oci_execute($rParsedQuery, OCI_DEFAULT);

Wenn Sie -1 durch die maximale Spaltenbreite ersetzen (d. H. 254), funktioniert dieser Code . Mit -1 verwendet oci_bind_by_param die aktuelle Länge des variablen Inhalts (in meinem Fall 0) als maximale Länge für diese Spalte. Dies führt bei der Ausführung zu ORA-01461.

0
David Gausmann

Hinzufügen eines weiteren Anwendungsfalls, bei dem dies der Fall war. Ich habe eine ADF Fusion-Anwendung verwendet und der verwendete Spaltentyp war ein Varchar2 (4000), der den Text und damit diesen Fehler nicht aufnehmen konnte.

0
Vik

Diese Fehlermeldung ist beim Versuch aufgetreten, String in eine XMLTYPE-Spalte einzufügen.

Speziell bei der Verwendung von Javas PreparedStatement wie folgt:

ps.setString('XML', document);

dabei ist XML hier als XMLTYPE definiert.

0
doughgle

Ich habe eine Lösung für Java/JPA/eclipselink/Oracle, wenn Sie eine lange XML-Zeichenfolge (> 4000) in eine XMLTYPE-Spalte unter Insert XML mit mehr als 4000 Zeichen in eine Oracle XMLTYPE-Spalte einfügen. Fügen Sie der Übersichtlichkeit halber hier den gleichen Inhalt bei, falls der Link nicht funktioniert

Sie müssen zunächst den XML-String für mehr als 4000 Zeichen in den SQLXML-Typ konvertieren.

Umgebung: jpa 2.1.0, eclipselink 2.5.2, Oracle db 11gr2

SQL:

CREATE TABLE "XMLTEST"
( "ID" NUMBER(10,0) NOT NULL ENABLE, 
  "DESCRIPTION" VARCHAR2(50 CHAR) NOT NULL ENABLE, 
  "XML_TXT" "XMLTYPE" NOT NULL ENABLE
);

INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (101, 'XML DATA', '<data>TEST</data>');
COMMIT;

DROP TABLE "XMLTEST";

Java-Code

String sql = "INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (?, ?, ?)";
String xmlDataStr = "<data>test...</data>"; // a long xml string with length > 4000 characters
Connection con = getEntityManager().unwrap(Connection.class);
SQLXML sqlXml = con.createSQLXML();
sqlXml.setString(xmlDataStr);

Java-Code - verwenden Sie PreparedStatement

PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setLong(1, 201);
pstmt.setLong(2, "Long XML Data");
pstmt.setSQLXML(3, sqlXml);
pstmt.execute();

Java-Code - Verwenden Sie eine native Abfrage anstelle von PreparedStatement

Query query = getEntityManager().createNativeQuery(sql);
query.setParameter(1, 301);
query.setParameter(2, "Long XML Data");
query.setParameter(3, sqlXml);
query.executeUpdate();
0
Jonathan L

Bei der Verwendung von Siebel REXPIMP (Registrierungsimport) beim Verwenden des neuesten Instant Client-Treibers ist das gleiche Problem aufgetreten. Verwenden Sie stattdessen den von Siebel bereitgestellten Data Direct-Treiber. Die DLL ist SEOR823.DLL

0
Rick Bahrenburg