ORA-01461: LONG 열에 삽입하는 경우에만 LONG 값을 바인딩할 수 있습니다. 쿼리 시 발생합니다.
개체를 쿼리하려고 하면 다음과 같은 오류가 발생합니다.
ORA-01461: can bind a LONG value only for insert into a LONG column
문제의 원인과 해결 방법을 누가 좀 도와주실 수 있나요?
varchar2 열에서도 발생할 수 있습니다.이것은 JDBC를 통한 Prepared Statements를 통해 간단히 재현할 수 있습니다.
- varchar2 컬럼(20 또는 임의의 길이)으로 테이블을 만듭니다.
- 20자 이상의 행이 있는 위의 표에 삽입할 것
위와 같이 타입이 잘못되거나 컬럼 너비가 초과될 수 있습니다.
또한 varchar2는 최대 4k자를 허용하므로 실제 제한은 2바이트의 경우 2k가 됩니다.
이 오류는 SQL 문에서 4000바이트보다 긴 varchar 변수를 사용하려고 할 때 발생합니다.PL/SQL은 최대 32767바이트의 varchar를 허용하지만 데이터베이스 테이블과 SQL 언어의 제한은 4000바이트입니다.SQL이 인식하지 못하는 PL/SQL 변수는 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;
좋아요, 그럼 코드를 보여주지 않았으니 몇 가지 추측을 해보죠
ORA-1461 에러에 근거해, 선택문에 LONG 데이터 타입을 지정한 것 같습니다.그걸 출력 변수에 연결하려고?그래요?오류는 매우 간단합니다.LONG 컬럼에 삽입하기 위한 LONG 값만 바인딩할 수 있습니다.
더 이상 무슨 말을 해야 할지 모르겠어요.이 오류는 상당히 자명하다.
일반적으로 LONG 데이터 타입에서 CLOB로 이동하는 것이 좋습니다.CLOB는 훨씬 더 잘 지원되며 LONG 데이터 타입은 하위 호환성을 위해서만 사용됩니다.
도움이 됐으면 좋겠다.
이 ORA-01461은 긴 열에 삽입할 때만 발생하는 것은 아닙니다.이 오류는 긴 문자열을 VARCHAR2 열에 삽입하기 위해 바인딩할 때 발생할 수 있으며, 가장 일반적으로 다중 바이트(oracle에서 단일 문자가 1바이트 이상의 공간을 차지할 수 있음) 문자 변환 문제가 있을 때 발생합니다.
데이터베이스가 UTF-8인 경우 각 문자가 최대 3바이트를 차지할 수 있기 때문에 3의 변환이 체크에 적용되어 varchar2(4000)에 삽입하는 데 1333 문자를 사용하도록 제한됩니다.
또 다른 솔루션은 데이터 유형을 varchar2(4000)에서 CLOB로 변경하는 것입니다.
내 동료와 나는 다음 사항을 알아냈다.
Microsoft 를 사용하는 경우.Oracle 데이터베이스(시스템)에 접속하기 위한 NET Oracle 드라이버.Data.OracleClient.Oracle Connection)
또한 database-parameter를 사용하여 CLOB 또는 NCLOB 필드에 2000~4000자 길이의 문자열을 삽입하려고 합니다.
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에서 이 버그에 대한 티켓을 오픈했지만 아직 수정되지 않았습니다.
도 같은 요.이치노VARCHAR
CLOB
이 링크가 도움이 되었습니다.
JDBC 10.1을 사용하는 어플리케이션에는 버그(Doc ID 370438.1)가 있어 삽입된 문자가 열의 최대 크기보다 작더라도 UTF8 문자 집합 데이터베이스 사용 시 동일한 ORA-01461 예외가 발생할 수 있습니다.
권장 솔루션: - 이 경우 10gR2 JDBC 드라이버 이상을 사용하십시오.
HTH
키란의 대답이 내 경우엔 확실히 정답이다.
코드 파트에서는 문자열을 4000자로 분할하여 db에 넣으려고 합니다.
이 에러와 함께 폭발합니다.
에러의 원인은 utf chars(각각 2바이트)를 사용하는 것입니다.코드(String 등)에서는 4000자로 잘라냅니다.Take(4000)), oracle은 문자열에 'ö' 또는 기타 eng 이외의 문자(정확한 것은 utf8로 2개 또는 바이트로 표시됨)가 포함된 경우 4001을 고려합니다.
꽤 오래된 질문인 것은 알지만, 나는 정확히 같은 오류를 가지고 있었고, 그것은 나의 어리석은 실수였다.
단순히 바이트 배열(pdf 파일)을 CLOB에 삽입하려고 하면 BLOB로 변경되어 문제가 해결되었습니다.
제가 실수를 깨닫기 전에 좋은 단서를 찾지 못했습니다(오류 메시지는 그다지 명확하지 않습니다). 그러면 제 답변이 다른 사람에게 도움이 될 수도 있습니다.
처음에 모든 CLOB 컬럼에서 엔티티 프레임워크 데이터베이스에 동일한 문제가 발생하였습니다.
회피책으로 삽입 조작에서는 텍스트 값을 4000 이상의 폭으로 채웠습니다(더 나은 솔루션은 제공되지 않았습니다).
XMLTYPE 열에 String을 삽입하려고 할 때 이 오류 메시지가 발생했습니다.
특히 Java의 Prepared Statement를 다음과 같이 사용합니다.
ps.setString('XML', document);
어디에XML
여기서 XMLTYPE으로 정의됩니다.
특히 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();
}
그리고 일했다.
이게 누구에게나 도움이 됐으면 좋겠어요.
최신 Instant Client 드라이버를 사용할 때 Siebel REXPIMP(레지스트리 가져오기)를 사용해도 동일한 문제가 발생했습니다.문제를 해결하려면 대신 Siebel에서 제공한 Data Direct 드라이버를 사용하십시오.DLL은SEOR823.DLL
이 문제를 발견한 다른 사용 사례를 추가합니다.ADF Fusion 어플리케이션을 사용하고 있었는데 사용하는 컬럼타입은 varchar2(4000)로 텍스트에 대응할 수 없었기 때문에 이 에러가 발생했습니다.
Java/J용 솔루션이 있습니다.4000자를 넘는 긴 XML 문자열을 Oracle XMLTYPE 열에 삽입할 때 PA/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";
자바 코드
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 코드 - Prepared Statement 사용
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();
PHP에서도 같은 문제가 발생하여 VARCHAR2 컬럼에 스테이트먼트를 준비했습니다.내 문자열이 VARCHAR2 크기를 초과하지 않았습니다.문제는 바인딩의 max length로 -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이 됩니다.
언급URL : https://stackoverflow.com/questions/9156019/ora-01461-can-bind-a-long-value-only-for-insert-into-a-long-column-occurs-when
'programing' 카테고리의 다른 글
블록으로 '셀프' 사이클 유지 (0) | 2023.04.19 |
---|---|
어레이/어레이 목록에서 링크된 목록을 사용하는 경우 (0) | 2023.04.19 |
UITextView 플레이스 홀더 (0) | 2023.04.19 |
쉬운 영어로 된 우코넨의 접미사 트리 알고리즘 (0) | 2023.04.19 |
curl 명령으로 특정 폴더에 파일 저장 (0) | 2023.04.19 |