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?
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?
Antworten:
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.
Dies kann auch bei varchar2-Spalten der Fall sein. Dies ist mit PreparedStatements über JDBC einfach reproduzierbar
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
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;
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();
Wir haben vor vielen Jahren bei Microsoft ein Ticket für diesen Fehler geöffnet, das jedoch noch nicht behoben wurde.
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.
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
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.
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).
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 XML
hier als XMLTYPE definiert ist.
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.
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
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();
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.