オブジェクトを照会しようとすると、次のエラーが発生します。
ORA-01461: can bind a LONG value only for insert into a LONG column
誰かが問題の原因と解決策について私を助けてくれますか?
わかりました、まあ、あなたはコードを表示しなかったので、ここでいくつかの仮定をします。
ORA-1461エラーに基づいて、select文でLONGデータ型を指定したようです?そして、それを出力変数にバインドしようとしていますか?そうですか?エラーは非常に単純です。 LONG列に挿入するためのLONG値のみをバインドできます。
他に何を言うべきかわからない。エラーはかなり自明です。
一般に、LONGデータ型からCLOBに移行することをお勧めします。 CLOBははるかによくサポートされており、LONGデータ型は実際には下位互換性のためにのみ存在します。
お役に立てば幸いです。
Varchar2列でも発生する可能性があります。これは、JDBCを介してPreparedStatementsを使用するだけでかなり再現可能です。
したがって、上記のように、タイプに誤りがあるか、列幅を超えている可能性があります。
また、varchar2は最大4k文字を許可しているため、実際の制限は2バイト文字の2kになります。
お役に立てれば
このエラーは、SQLステートメントで4000バイトを超えるvarchar変数を使用しようとすると発生します。 PL/SQLでは最大32767バイトのvarcharを使用できますが、データベーステーブルとSQL言語の制限は4000です。SQLがSQLステートメントで認識しないPL/SQL変数は使用できません。メッセージが説明しているように、例外は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;
私と同僚の次のことがわかりました。
Microsoft .NET Oracleドライバーを使用してOracleデータベース(System.Data.OracleClient.OracleConnection)に接続する場合
そして、データベースパラメータを使用して、2000〜4000文字の文字列をCLOBまたはNCLOBフィールドに挿入しようとしています。
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();
何年も前にマイクロソフトでこのバグのチケットをオープンしましたが、まだ修正されていません。
このORA-01461は、長い列への挿入中にのみ発生しません。このエラーは、挿入用の長い文字列をVARCHAR2列にバインドするときに発生する可能性があります。最も一般的なのは、マルチバイト(Oracleで単一の文字が複数のバイトスペースを取ることができる)文字変換の問題がある場合です。
データベースがUTF-8の場合、各文字は最大3バイトを使用できるため、3の変換がチェックに適用され、実際には1333文字を使用してvarchar2(4000)に挿入するように制限されます。
別の解決策は、データ型をvarchar2(4000)からCLOBに変更することです。
私は同じ問題に直面していたので、VARCHAR
をCLOB
に置き換えるだけで解決しました。これは link に役立ちました。
JDBC 10.1を使用するアプリケーションにはバグ(Doc ID 370438.1)があり、UTF8文字セットデータベースの操作中に、挿入された文字が列の最大サイズより小さくても、同じORA-01461例外をスローできます。
推奨される解決策:-このような場合は10gR2 JDBCドライバー以上を使用してください。
HTH
Kiran の答えは、私の場合の答えです。
コード部分では、文字列を4000文字の文字列に分割し、それらをdbに入れようとします。
このエラーで爆発します。
エラーの原因はutf文字を使用していることです。これらはそれぞれ2バイトをカウントします。コードで4000文字に切り捨てても(文字列。 utf8)文字。
私の特定のケースでは、Mybatisを使用して、Base64でエンコードされたファイルをテーブルのBLOBフィールドに保存しようとしました。
だから私の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>
そして私のDTOで:
String getPdf(){
return pdf;
}
これにより、Mybatisの脅威は文字列文字列であるかのようになり、Varcharとして保存しようとします。だから私の解決策は次のとおりでした:
私のDTOで:
Byte[] getPdf(){
return pdf.getBytes();
}
そして働いた。
これが誰にも役立つことを願っています。
最初にすべてのCLOB列でEntity Frameworkデータベースに同じ問題がありました。
回避策として、挿入操作で少なくとも4000の幅になるようにテキスト値をスペースで埋めました(これ以上の解決策はありませんでした)。
PHPとVARCHAR2列の準備されたステートメントを使用して同じ問題が発生しました。私の文字列はVARCHAR2サイズを超えていません。問題は、バインディングのmaxlengthとして-1を使用したことですが、変数の内容は後で変更されました。
例:
$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);
-1を最大列幅(つまり254)に置き換えると、このコードは機能します。 -1の場合、oci_bind_by_paramは、変数コンテンツの現在の長さ(この場合は0)をこの列の最大長として使用します。これにより、実行時にORA-01461が生成されます。
これが起こっていることがわかった別のユースケースを追加します。私はADF Fusionアプリケーションを使用しており、使用されている列タイプはvarchar2(4000)であり、テキストを収容できなかったため、このエラーが発生しました。
XMLTYPE列に文字列を挿入しようとしたときに、このエラーメッセージが表示されました。
具体的には、次のようにJavaのPreparedStatementを使用します。
ps.setString('XML', document);
ここで、XML
はXMLTYPEとして定義されています。
Oracle XMLTYPE列に4000文字を超えるXMLを挿入 でXMLTYPE列に長いxml文字列(> 4000)を挿入すると、Java/JPA/eclipselink/Oracleのソリューションがあります。明確にするために、リンクが機能しない場合に備えて同じ内容をここに含めてください
4000文字以上のXML文字列を最初にSQLXML型に変換する必要があります。
環境: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コード
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コード-PreparedStatementを使用
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setLong(1, 201);
pstmt.setLong(2, "Long XML Data");
pstmt.setSQLXML(3, sqlXml);
pstmt.execute();
Javaコード-PreparedStatementの代わりにネイティブクエリを使用する
Query query = getEntityManager().createNativeQuery(sql);
query.setParameter(1, 301);
query.setParameter(2, "Long XML Data");
query.setParameter(3, sqlXml);
query.executeUpdate();
最新のインスタントクライアントドライバーを使用しているときに、Siebel REXPIMP(レジストリインポート)を使用しても同じ問題が発生しました。問題を解決するには、代わりにSiebelが提供するData Directドライバーを使用します。 DLLはSEOR823.DLL
です