programing

Oracle JDBC 및 Oracle CHAR 데이터 유형

css3 2023. 10. 27. 22:04

Oracle JDBC 및 Oracle CHAR 데이터 유형

Oracle JDBC 드라이버의 처리에 까다로운 문제가 있습니다.CHAR데이터 유형입니다.간단한 표를 살펴봅시다.

create table x (c char(4));
insert into x (c) values ('a');  -- inserts 'a   '

그래서 제가 뭔가를 집어넣을 때CHAR(4), 문자열은 항상 공백으로 채워집니다.이 작업은 다음과 같은 쿼리를 실행할 때도 수행됩니다.

select * from x where c = 'a';    -- selects 1 record
select * from x where c = 'a ';   -- selects 1 record
select * from x where c = 'a   '; -- selects 1 record

여기 상수가'a'빈 공간으로 가득 차 있습니다.그래서 항상 기록이 되돌아오는 겁니다.이는 이러한 쿼리를 JDBC를 사용하여 실행할 때 참으로 유지됩니다.PreparedStatement뿐만 아니라.까다로운 것은 바인딩 변수를 사용하려는 경우입니다.

PreparedStatement stmt = 
  conn.prepareStatement("select * from x where c = ?");
stmt.setString(1, "a");    // This won't return any records
stmt.setString(1, "a   "); // This will return a record
stmt.executeQuery();

다음은 해결 방법입니다.

PreparedStatement stmt = 
  conn.prepareStatement("select * from x where trim(c) = trim(?)");
stmt.setString(1, "a");    // This will return a record
stmt.setString(1, "a   "); // This will return a record
stmt.executeQuery();

EDIT: 제약 조건은 다음과 같습니다.

  • 위 해결책은 두 내용을 모두 수정하는 것이므로 바람직하지 않습니다.c그리고.?, 인덱스를 사용하여 다음과 같은 작업을 수행할 수 있습니다.c상당히 딱딱한
  • 열 이동 위치CHAR로.VARCHAR(물론 그렇게 되어야 함) 가능하지 않습니다.

EDIT: 이러한 제약의 이유는 데이터베이스 추상화 라이브러리인 jOOQ의 개발자 입장에서 이 질문을 하기 때문입니다.그래서 저의 요구사항은 jOOQ의 클라이언트 코드에 있는 어떤 것도 깨지지 않는 매우 포괄적인 솔루션을 제공하는 것입니다.그것이 제가 이 해결책을 별로 좋아하지 않는 이유입니다.그래서 제가 접근할 수 없는 겁니다CHAR칼럼의 선언그래도 난 이 사건을 처리할 수 있었으면 좋겠어요.

대신 무엇을 하시겠습니까?처리하는 데 좋은 방법이 무엇입니까?CHAR후행 공백을 무시하고 싶을 때의 데이터 유형?

네가 원한다면

stmt.setString(1, "a");    // This won't return any records

레코드를 반환하려면, 시도해 보세요.

conn.prepareStatement("select * from x where c = cast(? as char(4))")

오라클에서 char(1)이더라도 char data type을 사용할 이유가 없습니다.대신 데이터 종류를 바꿔주실 수 있나요?

개리의 해결책은 잘 통합니다.여기 대안이 있습니다.

Oracle JDBC 드라이버를 사용할 경우prepareStatement()실제로 돌려줄 것입니다.OraclePreparedStatement, 가 있는.setFixedCHAR()입력 내용을 공백으로 자동으로 패드하는 방법입니다.

String sql = "select * from x where c = ?";
OraclePreparedStatement stmt = (OraclePreparedStatement) conn.prepareStatement(sql);
stmt.setFixedCHAR(1, "a");
...

분명히 캐스팅은 Oracle 드라이버를 사용하는 경우에만 안전합니다.

개리의 답변보다 이것을 사용하는 것을 제안하는 유일한 이유는 JDBC 코드를 수정할 필요 없이 칼럼 크기를 변경할 수 있기 때문입니다.운전자는 개발자가 칼럼 크기를 알고 관리할 필요 없이 정확한 숫자의 스페이스를 패드에 부착합니다.

이것에 대해 좋은 해결책이 있습니다.데이터베이스에서 연결을 가져오는 동안 하나의 속성을 추가해야 합니다.

NLS_LANG=american_america.AL32UTF8

또는 자바 연결에서 아래 코드를 사용할 수 있습니다.

java.util.Properties info = new java.util.Properties();
info.put ("user", user);
info.put ("password",password);
info.put("fixedString","TRUE");
info.put("NLS_LANG","american_america.AL32UTF8");
info.put("SetBigStringTryClob","TRUE");
String url="jdbc:oracle:thin:@"+serverName;
log.debug("url="+url);
log.debug("info="+info);
Class.forName("oracle.jdbc.OracleDriver");
conn  = DriverManager.getConnection(url,info);

다른 방법은 당신의 sqlas를 수정하는 것입니다.

select * from x where NVL(TRIM(c),' ') = NVL(TRIM('a'),' ')

업데이트 쿼리의 열 이름에 RTRIM()을 추가하기만 하면 됩니다.

언급URL : https://stackoverflow.com/questions/5332845/oracle-jdbc-and-oracle-char-data-type