code

ORA-01461 : LONG 열에 삽입하기 위해서만 LONG 값을 바인드 할 수 있습니다-질의시 발생합니다

codestyles 2020. 11. 22. 19:47
반응형

ORA-01461 : LONG 열에 삽입하기 위해서만 LONG 값을 바인드 할 수 있습니다-질의시 발생합니다


개체를 쿼리하려고하면 다음 오류가 발생합니다.

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

누군가가 문제의 원인과 해결책에 대해 나를 도울 수 있습니까?


좋습니다. 코드를 보여주지 않았으므로 여기서 몇 가지 가정을하겠습니다.

ORA-1461 오류에 따르면 select 문에 LONG 데이터 유형을 지정한 것 같습니다. 그리고 출력 변수에 바인딩하려고합니까? 맞습니까? 오류는 매우 간단합니다. LONG 열에 삽입하기 위해 LONG 값만 바인딩 할 수 있습니다.

다른 말을해야할지 모르겠습니다. 오류는 매우 자명합니다.

일반적으로 LONG 데이터 유형에서 CLOB로 이동하는 것이 좋습니다. CLOB는 훨씬 더 잘 지원되며 LONG 데이터 유형은 실제로 이전 버전과의 호환성을 위해서만 존재합니다.

다음 은 LONG 데이터 유형 제한 목록입니다.

도움이되기를 바랍니다.


varchar2 열에서도 발생할 수 있습니다. 이것은 JDBC를 통해 PreparedStatements로 간단하게 재현 할 수 있습니다.

  1. varchar2 (20 또는 임의의 길이) 열이있는 테이블 생성 및
  2. 20 자 이상의 행이있는 위의 테이블에 삽입

따라서 위에서 말했듯이 유형 또는 열 너비가 초과되었을 수 있습니다.

또한 varchar2는 최대 4k 문자를 허용하므로 실제 제한은 2 바이트 문자의 경우 2k입니다.

도움이 되었기를 바랍니다


이 오류는 SQL 문에서 4000 바이트보다 긴 varchar 변수를 사용하려고 할 때 발생합니다. PL / SQL은 최대 32767 바이트의 varchar를 허용하지만 데이터베이스 테이블 및 SQL 언어의 제한은 4000입니다. SQL 문에서 SQL이 인식하지 못하는 PL / SQL 변수는 사용할 수 없습니다. 메시지에서 설명 하듯이 예외는 긴 유형 열에 직접 삽입하는 것입니다.

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();
  • 길이가 2000 자 미만인 모든 문자열은이 예외를 발생시키지 않습니다.
  • 4000 자보다 긴 문자열은이 예외를 발생시키지 않습니다.
  • 길이가 2000 ~ 4000 자 사이 인 문자열에서만이 예외가 발생합니다.

몇 년 전에 Microsoft에서이 버그에 대한 티켓을 열었지만 아직 수정되지 않았습니다.


이 ORA-01461은 Long 열에 삽입하는 동안에 만 발생하지 않습니다. 이 오류는 VARCHAR2 열에 삽입하기 위해 긴 문자열을 바인딩 할 때 발생할 수 있으며 다중 바이트 (오라클에서 단일 문자가 둘 이상의 바이트 공간을 차지할 수 있음을 의미 함) 문자 변환 문제가있을 때 가장 일반적으로 발생합니다.

데이터베이스가 UTF-8이면 각 문자가 최대 3 바이트를 차지할 수 있기 때문에 3의 변환이 검사에 적용되므로 실제로는 1333 문자를 사용하여 varchar2 (4000)에 삽입하도록 제한됩니다.

또 다른 해결책은 데이터 유형을 varchar2 (4000)에서 CLOB로 변경하는 것입니다.


저도 같은 문제에 직면하고 단지 대체하여 그것을 해결했다 VARCHAR으로 CLOB. 링크 는 나를 도왔습니다.


JDBC 10.1을 사용하는 응용 프로그램에는 버그 (문서 ID 370438.1)가 있으며 삽입 된 문자가 열의 최대 크기보다 작더라도 UTF8 문자 집합 데이터베이스로 작업하는 동안 동일한 ORA-01461 예외가 발생할 수 있습니다.

권장 솔루션 :-이 경우 10gR2 JDBC 드라이버 이상을 사용하십시오.

HTH


Kiran 의 대답은 분명히 제 경우에 대한 대답입니다.

코드 부분에서 문자열을 4000 자 문자열로 분할하고 db에 넣으려고합니다.

이 오류와 함께 폭발합니다.

오류의 원인은 각각 2 바이트를 계산하는 utf 문자를 사용하는 것입니다. 내가 코드에서 4000 자 (예 : String.Take (4000))로 자른 경우에도 오라클은 문자열에 'ö'또는 기타 비 eng (비 ASCII가 정확하지 않은 경우 2 또는 바이트로 표현됨)이 포함 된 경우 4001을 고려합니다. utf8) 문자.


모든 CLOB 열에서 먼저 Entity Framework 데이터베이스와 동일한 문제가 발생했습니다.

해결 방법으로 삽입 작업에서 너비가 4000 이상이되도록 텍스트 값을 공백으로 채웠습니다 (더 나은 솔루션은 제공되지 않음).


제 경우에는 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 위협을 String char 시퀀스 인 것처럼 만들고 Varchar로 저장하려고합니다. 그래서 내 해결책은 다음과 같습니다.

내 DTO에서 :

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

그리고 일했습니다.

나는 이것이 누구에게나 도움이되기를 바랍니다.


I encountered the same problem using Siebel REXPIMP (registry import) when using the latest Instant Client driver. To fix the issues, use the Siebel provided Data Direct driver instead. The DLL is SEOR823.DLL


Adding another use case where I found this happening. I was using a ADF Fusion application and the column type being used was a varchar2(4000) which could not accommodate the text and hence this error.


I encountered this error message when trying to insert String into an XMLTYPE column.

Specifically using Java's PreparedStatement like this:

ps.setString('XML', document);

where XML here is defined as XMLTYPE.


I have a solution for Java/JPA/eclipselink/oracle when insert a long xml string (>4000) into a XMLTYPE column at Insert XML with more than 4000 characters into a Oracle XMLTYPE column. For clarity, include the same contents here in case the link not working

You need to convert xml string for more than 4000 charcaters into SQLXML type first.

Environment: 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 - use PreparedStatement

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

Java code - use native query instead of PreparedStatement

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

I had the same problem using PHP and prepared statements on a VARCHAR2 column. My string didn't exceeed the VARCHAR2 size. The problem was that I used -1 as maxlength for binding, but the variable content changed later.

In example:

$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);

If you replace the -1 with the max column width (i. e. 254) then this code works. With -1 oci_bind_by_param uses the current length of the variable content (in my case 0) as maximum length for this column. This results in ORA-01461 when executing.

참고URL : https://stackoverflow.com/questions/9156019/ora-01461-can-bind-a-long-value-only-for-insert-into-a-long-column-occurs-when

반응형