programing

DB에서 마지막으로 삽입된 행의 값

yellowcard 2023. 9. 17. 12:14
반응형

DB에서 마지막으로 삽입된 행의 값

마지막으로 삽입된 행에서 값을 얻을 수 있는 방법이 있습니까?

생성된 시퀀스로 인해 PK가 자동으로 증가하는 행을 삽입하고 있는데, 이 시퀀스 번호를 받고 싶습니다.테이블에서 PK만 고유하게 보장됩니다.

저는 JDBC와 오라클로 자바를 사용하고 있습니다.

제가 깜빡하고 이 값을 아래 결과 집합을 사용해서 검색하고 싶습니다.(mysql로 시도해 보았는데 성공적으로 작동했습니다만 Oracle로 전환해야 했고 현재 ID의 문자열 표현이 나오고 있고 실제 시퀀스 번호가 표시되지 않습니다.)

Statement stmt = conn.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
stmt.RETURN_GENERATED_KEYS;
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
   log.info("Successful insert");
   id = rs.getString(1);
}

위의 토막글은 mysql 테이블에 저장된 열 int 값을 반환합니다.그런데 Oracle로 전환한 이후로 반환되는 값이 이상한 문자열 값이 되었습니다.

당신이 하려는 것은 당신이 하려는 것은RETURNING예제 테이블과 시퀀스를 설정해 보겠습니다.

CREATE TABLE "TEST" 
( "ID" NUMBER NOT NULL ENABLE, 
 "NAME" VARCHAR2(100 CHAR) NOT NULL ENABLE, 
  CONSTRAINT "PK_TEST" PRIMARY KEY ("ID")
  );

CREATE SEQUENCE SEQ_TEST;

이제 Java 코드는 다음과 같이 나타납니다.

String insertSql = "BEGIN INSERT INTO TEST (ID, NAME) VALUES (SEQ_TEST.NEXTVAL(), ?) RETURNING ID INTO ?; END;";
java.sql.CallableStatement stmt = conn.prepareCall(insertSql);
stmt.setString(1, "John Smith");
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
stmt.execute();
int id = stmt.getInt(2);

이는 다른 데이터베이스와 일치하지 않지만 Oracle을 사용할 경우getGeneratedKeys()사용할 때 삽입된 행의 ROWID를 반환합니다.Statement.RETURN_GENERATEDKEYS. 그래서 당신은 당신이 사용할 필요가 있습니다.oracle.sql.ROWID이를 "읽을" 수 있는 독점 유형:

Statement stmt = connection.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
oracle.sql.ROWID rid = (oracle.sql.ROWID) rs.getObject(1); 

하지만 이렇게 해서 PK의 ID가 생성되지는 않습니다.Oracle을 사용할 때는 메서드를 사용하거나 생성된 시퀀스 값을 가져오는 대신 사용해야 합니다.(인덱스 또는 기본 키 열의 이름과 일치하도록 값을 조정) 다음과 같은 것입니다.

stmt.executeUpdate(INSERT_SQL, new int[] {1});
ResultSet rs = stmt.getGeneratedKeys();

아니면

stmt.executeUpdate(INSERT_SQL, new String[] {"ID"});
ResultSet rs = stmt.getGeneratedKeys();

이 부분에 대해서 좀 더 자세히 조사를 해보니까 스프링 문서(여기서 언급한 바와 같이)에 이런 접근법이 나와 있는 것 같아요. 그러니까 완전히 틀릴 수는 없는 것 같아요.그러나 안타깝게도 휴대성이 좋지 않고 다른 플랫폼에서는 작동하지 않을 수 있습니다.

당신은 사용해야 합니다.ResultSet#getLong()대신.허망하면 해보세요.ResultSet#getRowId()그리고 결국에는 그것을.oracle.sql.ROWID. 반환된 16진수 문자열이 실제로 16진수 맛의 ID일 경우 다음과 같이 10진수로 변환할 수 있습니다.Long#valueOf()아니면Integer#valueOf().

Long id = Long.valueOf(hexId, 16);

의 JDBC 을 지원하지 않았습니다.ResultSet#getGeneratedKeys()오랜 시간동안 그리고 아직도 그것에 대해 다소 골치아프습니다.만약 그 말을 제대로 할 수 없다면, 당신은 그 말을 실행할 필요가 있습니다.SELECT CURRVAL(sequencename)이 한 insert, 이 a, 의 이 한 이 PreparedStatement 기본 예:

public void create(User user) throws SQLException {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    Statement statement = null;
    ResultSet generatedKeys = null;

    try {
        connection = daoFactory.getConnection();
        preparedStatement = connection.prepareStatement(SQL_INSERT);
        preparedStatement.setValue(1, user.getName());
        // Set more values here.
        int affectedRows = preparedStatement.executeUpdate();
        if (affectedRows == 0) {
            throw new SQLException("Creating user failed, no rows affected.");
        }
        statement = connection.createStatement();
        generatedKeys = statement.executeQuery(SQL_CURRVAL);
        if (generatedKeys.next()) {
            user.setId(generatedKeys.getLong(1));
        } else {
            throw new SQLException("Creating user failed, no generated key obtained.");
        }
    } finally {
        close(generatedKeys);
        close(statement);
        close(preparedStatement);
        close(connection);
    }
}

오, 당신의 코드 예시에서 다음 행이

stmt.RETURN_GENERATED_KEYS;

전혀 불필요한 것입니다.제거.

여기에 제가 생성된 키를 얻는 것에 대해 이전에 게시했던 또 다른 예를 찾을 수 있습니다. 그것은 일반적인 키를 사용합니다.getGeneratedKeys()접근.

언급URL : https://stackoverflow.com/questions/1976625/value-from-last-inserted-row-in-db

반응형