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

72

Wenn ich versuche, Objekte abzufragen, wird der folgende Fehler angezeigt:

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?

Rupesh
quelle
@ Rupesh bist du sicher, dass dies aus einer Abfrage stammt? Versuchen Sie vielleicht, eine Einfügung zu machen? Auch wie ist dieser Lauf (Java, C #, sqlplus ,?)
tbone
1
Es gibt PL / SQL-Problemumgehungen für die Verwendung langer Zeichenfolgenliterale zum Einfügen in CLOB- und BLOB- Spalten.
Vadzim

Antworten:

19

Ok, da Sie keinen Code angezeigt haben, werde ich hier einige Annahmen treffen.

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

Ich bin mir 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 viel besser unterstützt, und LANGE Datentypen dienen nur der Abwärtskompatibilität.

Hier ist eine Liste der langen Datentypeinschränkungen

Hoffentlich hilft das.

Mark J. Bobak
quelle
14
Der Fehler kann auftreten, ohne dass eine Tabelle mit einem LONG-Typ erkennbar bearbeitet wird.
Gus Crawford
1
Ich habe es bekommen, als ich versucht habe, einige Daten mit einem CLOB in einer Tabelle zusammenzuführen
dougd_in_nc
19
Leider ist die Fehlermeldung nicht sehr selbsterklärend, wenn sie durch ein varchar2-Feld verursacht wird, das seine Feldlänge überschreitet (siehe Antwort von Kiran)
max.mustermann
3
Ich konnte nicht nach unten scrollen und erkannte, dass Kiran die bessere Antwort hatte. Ich mag die Idee nicht, wie die akzeptierte Antwort oben steht. Es sollte eine Möglichkeit geben, sie auf den zweiten Platz zu bringen, wenn eine andere Antwort viel mehr positive Stimmen erhält.
CoderSteve
2
Dies geschieht auch dann, wenn Sie versuchen, mehr Zeichen als die für die varchar-Spalte angegebene Größe einzugeben. Beispiel: varchar (4000): Wenn Sie 4001 Zeichen eingeben, wird dieser Fehler angezeigt.
Laura Liparulo
198

Dies kann auch bei varchar2-Spalten der Fall sein. 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 erwähnt, kann dies bei Typen falsch sein oder die Spaltenbreite wird überschritten.

Beachten Sie auch, dass varchar2 maximal 4k Zeichen zulässt und das tatsächliche Limit für Doppelbytezeichen 2k beträgt

Hoffe das hilft

Kiran
quelle
15
In einer Oracle-Datenbank habe ich eine Tabelle mit der Spalte VARCHAR2 (2000 CHAR). Ich sehe sowohl den ORA-01461 (ungefähr diesen langen Wert) als auch einen weiteren Fehler ORA-12899. Der ORA-12899 gibt das Problem genau an: tatsächliche Länge: 2392, maximale Länge: 2000. Es scheint, dass die Art von irreführendem ORA-01461 zurückgegeben wird, wenn der Inhalt> 4000 CHAR ist, was das von Oracle maximal unterstützte ist. Während der ORA-12899 zurückgegeben wird, wenn die Länge> 2000 und <4000 ist. Kann jemand dies bestätigen (zumindest für Oracle)?
Vering
5
@Vering, kann bestätigen. Wir bekommen das gleiche Verhalten.
Grant H.
1
Das war es, was wirklich für uns geschah.
Mathew Berg
Ich hatte die ORA-01461 für eine Spalte von VARCHAR2 (2000).
Marcel
1
Warum erzeugt Oracle in diesem Fall aus Neugier einen solchen arkanen Fehler?
Seldon
35

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 bis zu 32767 Byte, aber das Limit für Datenbanktabellen und SQL-Sprache liegt bei 4000. Sie können keine PL / SQL-Variablen verwenden, die SQL in SQL-Anweisungen nicht erkennt. Eine Ausnahme ist, wie in der Nachricht erläutert, das direkte Einfügen in eine Spalte vom Typ Long.

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;
Tomasz Żuk
quelle
8

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)

Und wir versuchen, eine Zeichenfolge mit einer Länge zwischen 2000 und 4000 Zeichen mithilfe eines Datenbankparameters in ein CLOB- oder NCLOB-Feld 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();
  • Zeichenfolgen mit einer Länge von weniger als 2000 Zeichen lösen diese Ausnahme nicht aus
  • Zeichenfolgen mit einer Länge von mehr als 4000 Zeichen lösen 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 bei Microsoft ein Ticket für diesen Fehler geöffnet, das jedoch noch nicht behoben wurde.

Markus1980Wien
quelle
Wir haben das gleiche Problem. Haben Sie eine vernünftige Problemumgehung?
Jeromerg
Verwenden Sie nach Möglichkeit Oracle.ManagedDataAccess.dll. (Kann frei bereitgestellt werden, ohne dass ein Oracle-Client auf Client-Computern installiert werden muss). [erfordert.NET 4.0] Wenn Sie nicht zu einem anderen .NET DataProvider wechseln können, gibt es einige mögliche Problemumgehungen, die ich mir vorstellen kann: Wir haben XML-Daten oder lesbaren Text in solchen Feldern gespeichert. Wir haben also Leerzeichen angehängt (wenn die Länge der Zeichenfolge zwischen 2000 und 4000 Zeichen lag). Eine andere mögliche Lösung wäre, die Zeichenfolgenlänge in einem zusätzlichen Datenbankfeld zu speichern, Leerzeichen anzuhängen, wenn die Zeichenfolgenlänge zwischen 2000 und 4000 Zeichen liegt, und die Längeninformationen zu verwenden im zusätzlichen Feld, um die Zeichenfolge beim Lesen zu schneiden.
Markus1980Wien
8

Dieser ORA-01461 tritt nicht nur beim Einfügen in eine lange Spalte auf. Dieser Fehler kann auftreten, wenn eine lange Zeichenfolge zum Einfügen in eine VARCHAR2-Spalte gebunden wird. Er tritt am häufigsten auf, wenn ein Problem bei der Zeichenkonvertierung mit mehreren Bytes (dh, ein einzelnes Zeichen kann mehr als ein Byte Platz in Oracle beanspruchen) vorliegt.

Wenn die Datenbank UTF-8 ist, wird aufgrund der Tatsache, dass jedes Zeichen bis zu 3 Bytes aufnehmen kann, die Konvertierung von 3 zur Überprüfung angewendet und ist daher tatsächlich 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.

Murali
quelle
4

Ich war vor dem gleichen Problem und lösen es nur durch Austausch VARCHARmit CLOB. Dieser Link hat mir geholfen.

aneela
quelle
3

Anwendungen, die JDBC 10.1 verwenden, haben einen Fehler (Doc ID 370438.1) und können bei der Arbeit mit der UTF8-Zeichensatzdatenbank dieselbe ORA-01461-Ausnahme auslösen, obwohl eingefügte Zeichen kleiner als die maximale Größe der Spalte sind.

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

HTH

pahariayogi
quelle
2

Kiran ‚s Antwort ist definitiv die Antwort für meinen Fall.

Im Codeteil habe ich die Zeichenfolge in 4000 Zeichenfolgen aufgeteilt und versucht, sie in db einzufügen.

Explodiert mit diesem Fehler.

Die Ursache des Fehlers ist die Verwendung von utf-Zeichen, die jeweils 2 Bytes zählen. Selbst wenn ich im Code auf 4000 Zeichen abschneide (etw. Wie String.Take (4000)), berücksichtigt Orakel 4001, wenn der String 'ö' oder ein anderes Nicht-Eng (genauer gesagt Nicht-ASCII) enthält, die mit zwei oder Bytes in dargestellt werden utf8) Zeichen.

mkb
quelle
1

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, die bei Einfügevorgängen mindestens 4000 breit sein sollten (es gab keine bessere Lösung).

Martin Staufcik
quelle
1

Diese Fehlermeldung ist aufgetreten, als ich versucht habe, einen String in eine XMLTYPE-Spalte einzufügen.

Speziell mit Java PreparedStatement wie folgt:

ps.setString('XML', document);

wobei XMLhier als XMLTYPE definiert ist.

Doughgle
quelle
Wie haben Sie dieses Problem behoben?
Acroyear vor
1

In meinem speziellen Fall habe ich versucht, eine Base64-codierte Datei mithilfe von Mybatis in einem Tabellen-BLOB-Feld zu speichern.

Also hatte ich in meiner XML:

<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;
}

Das bedroht Mybatis wie eine String-Zeichenfolge und versucht, sie als Varchar zu speichern. Meine Lösung war also folgende:

In meinem DTO:

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

Und gearbeitet.

Ich hoffe das konnte jedem helfen.

Francisco M.
quelle
0

Beim Verwenden von Siebel REXPIMP (Registrierungsimport) bei Verwendung des neuesten Instant Client-Treibers ist dasselbe Problem aufgetreten. Verwenden Sie stattdessen den von Siebel bereitgestellten Data Direct-Treiber, um die Probleme zu beheben. Die DLL istSEOR823.DLL

Rick Bahrenburg
quelle
0

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

Vik
quelle
0

Ich habe eine Lösung für Java / JPA / eclipselink / oracle beim Einfügen einer langen XML-Zeichenfolge (> 4000) in eine XMLTYPE-Spalte unter Einfügen von XML mit mehr als 4000 Zeichen in eine Oracle XMLTYPE-Spalte . Fügen Sie hier zur Verdeutlichung denselben Inhalt ein, falls der Link nicht funktioniert

Sie müssen zuerst die XML-Zeichenfolge 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();
Jonathan L.
quelle
0

Ich hatte das gleiche Problem mit PHP und bereitete Anweisungen für eine VARCHAR2-Spalte vor. Meine Zeichenfolge hat die Größe VARCHAR2 nicht überschritten. Das Problem war, dass ich -1 als maximale Länge für die Bindung verwendet habe, aber der Inhalt der Variablen 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 (dh 254) ersetzen, 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.

David Gausmann
quelle