programing

유효하지 않은 문자(ORA-00911)는 어디에 있습니까?

magicmemo 2023. 4. 1. 09:00
반응형

유효하지 않은 문자(ORA-00911)는 어디에 있습니까?

삽입하려고 합니다.CLOB를 데이터베이스로 변환합니다(관련 질문 참조).뭐가 문제인지 잘 모르겠어요.테이블에 삽입하고 싶은 약 85개 정도의 리스트가 있습니다.첫 번째 딱지만 넣어도ORA-00911: invalid character그 진술서를 어떻게 꺼내야 할지 모르겠어요PreparedStatement이게 실행되기 전에, 그게 맞는지 100% 확신할 수는 없지만, 내가 맞혔다면, 정확히 이렇게 생겼을 거야:

insert all
  into domo_queries values ('select 
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = ''CHQ PeopleSoft FS''')
select * from dual;

궁극적으로, 이 진술은 많은 것을 포함할 것이다.into그래서 그냥 규칙적인 행동을 하지 않는 거야insert진술.잘못된 문자는 보이지 않습니다. (아, 위의 코드는 sql developer tool에서 실행하면 정상적으로 실행됩니다.)그리고 만약 내가 반콜론을 제거한다면PreparedStatement, 그것은, 을 던집니다.ORA-00933: SQL command not properly ended에러입니다.

어떤 경우에도 쿼리를 실행하기 위한 코드(및 위의 예에서는 변수 값)는 다음과 같습니다.

public ResultSet executeQuery(String connection, String query, QueryParameter... params) throws DataException, SQLException {
  // query at this point = "insert all
                          //into domo_queries values (?)
                          //select * from dual;"
  Connection conn = ConnectionPool.getInstance().get(connection);
  PreparedStatement pstmt = conn.prepareStatement(query);
  for (int i = 1; i <= params.length; i++) {
    QueryParameter param = params[i - 1];
    switch (param.getType()) { //The type in the example is QueryParameter.CLOB
      case QueryParameter.CLOB:
        Clob clob = CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_SESSION);
        clob.setString(i, "'" + param.getValue() + "'");
        //the value of param.getValue() at this point is:
        /*
         * select 
         * substr(to_char(max_data),1,4) as year,
         * substr(to_char(max_data),5,6) as month,
         * max_data
         * from dss_fin_user.acq_dashboard_src_load_success
         * where source = ''CHQ PeopleSoft FS''
         */
        pstmt.setClob(i, clob);
        break;
      case QueryParameter.STRING:
        pstmt.setString(i, "'" + param.getValue() + "'");
        break;
    }
  }
  ResultSet rs = pstmt.executeQuery(); //Obviously, this is where the error is thrown
  conn.commit();
  ConnectionPool.getInstance().release(conn);
  return rs;
}

제가 놓친 게 있나요?

표시된 대로 스트링 리터럴을 사용할 경우 문제는;마지막 글자입니다.JDBC 콜의 쿼리 스트링에는 이 값을 포함할 수 없습니다.

하나의 행만 삽입하기 때문에 일반 행은INSERT여러 행을 삽입해도 문제 없습니다.엉터리 문장을 사용하는 것이 어떤 경우에도 더 효율적일 수 있다.필요 없다INSERT ALL게다가 임시 클롭 같은 것도 필요 없습니다.다음과 같이 메서드를 단순화할 수 있습니다(파라미터가 올바르다고 가정).

String query1 = "select substr(to_char(max_data),1,4) as year, " + 
  "substr(to_char(max_data),5,6) as month, max_data " +
  "from dss_fin_user.acq_dashboard_src_load_success " + 
  "where source = 'CHQ PeopleSoft FS'";

String query2 = ".....";

String sql = "insert into domo_queries (clob_column) values (?)";
PreparedStatement pstmt = con.prepareStatement(sql);
StringReader reader = new StringReader(query1);
pstmt.setCharacterStream(1, reader, query1.length());
pstmt.addBatch();

reader = new StringReader(query2);
pstmt.setCharacterStream(1, reader, query2.length());
pstmt.addBatch();

pstmt.executeBatch();   
con.commit();

제 머리 꼭대기에서 문자열 리터럴에 'q' 연산자를 써볼 수 있나요?

비슷한 것

insert all
  into domo_queries values (q'[select 
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = 'CHQ PeopleSoft FS']')
select * from dual;

술어의 작은 따옴표는 이스케이프되지 않으며 문자열은 q'[...] 사이에 있습니다.

그 이유 중 하나는 테이블 열의 이름에 밑줄(_)이 있는 경우입니다.이 문자는 JDBC에 의해 비활성 문자로 간주됩니다.ALTER 명령으로 컬럼 이름을 변경하고 를 수정하는 코드 SQL 을 변경합니다.

Oracle에서는 ORA-00911에 대해 설명합니다.Oracle SQL Developer에서 SQL 요청을 실행한 후 이 설명을 볼 수 있습니다.

ORA-00911.00000 - "잘못된 문자" *원인: 식별자는 문자와 숫자 이외의 ASCII 문자로 시작할 수 없습니다.$#_도 첫 번째 문자 뒤에 사용할 수 있습니다.큰따옴표로 둘러싸인 식별자에는 큰따옴표 이외의 문자를 포함할 수 있습니다.대체 따옴표(q'#...)#'는 공백, 탭 또는 캐리지 리턴을 구분자로 사용할 수 없습니다.기타 모든 컨텍스트에 대해서는 SQL Language Reference Manual을 참조하십시오.

하지만 당신의 경우는 이중으로 보입니다.

언급URL : https://stackoverflow.com/questions/10728377/wheres-my-invalid-character-ora-00911

반응형