2013-03-06 3 views
5

표준 SQL "UPSERT"문을 찾고 있습니다. 삽입 및 업데이트가 있으면 호출합니다.SQL 표준 UPSERT 호출

나는 효율적이고 효율적인 크로스 플랫폼 호출을 찾고 있습니다.

나는 MERGE, UPSERT, REPLACE, INSERT .. ON DUPLICATE UPDATE을 본 적이 있지만 문은 요구 사항을 충족하지 않습니다.

BTW MYSQL과 HSQLDB를 사용합니다. 나는 HSQLDB가 제한되어 있고 내가 필요로하는 것을 다루지 않을 수도 있다는 것을 이해한다.하지만 HSQLDB가 없어도 표준 방법을 찾을 수 없었다. MYSQL과 HSQLDB만으로도 충분할 것입니다.

저는 한동안 주변을 둘러 보았고 대답을 얻을 수 없었습니다.

내 테이블 :

CREATE TABLE MY_TABLE (
    MY_KEY varchar(50) NOT NULL , 
    MY_VALUE varchar(50) DEFAULT NULL, 
    TIME_STAMP bigint NOT NULL, 
    PRIMARY KEY (MY_KEY) 
); 

어떤 생각?

고맙습니다)

+0

'INSERT .. 중복 UPDATE'가 mYSQL''의 핵심은 켜짐입니다. 몇 가지 레코드 또는 테이블 구조를 보여줄 수 있습니까? –

+0

그래도 MYSQL에서만 지원됩니다. HSQLDB와 다른 모든 사람들은 그것을 사용하지 않습니다 ... – BobTheBuilder

+0

ANSI 병합 (http://en.wikipedia.org/wiki/Merge_%28SQL%29)이 있지만 모든 DBMS에서 구현되지 않았습니다. 보편적 인 명령에 대한 희망이 없습니다. –

답변

4

MySQL과 HSQLDB에서 모두 지원되는 유일한 솔루션은 바꾸려는 행을 쿼리하고 조건부로 INSERT 또는 UPDATE를 쿼리하는 것입니다. 즉, RDBMS 구현 간의 차이를 보완하기 위해 더 많은 응용 프로그램 코드를 작성해야합니다.

  1. START TRANSACTION
  2. SELECT ... FOR UPDATE.
  3. SELECT가 행을 찾으면 업데이트하십시오.
  4. 그렇지 않으면 INSERT.
  5. COMMIT.

MySQL은 ANSI SQL MERGE 문을 지원하지 않습니다. DUPLICATE KEY UPDATE에서 REPLACE 및 INSERT ...를 지원합니다. 그것에 대한 자세한 내용은 "INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"에 대한 내 대답을 참조하십시오.


덧글 : 예, 다른 접근법은 INSERT를 시도하고 성공했는지 확인하는 것입니다. 그렇지 않으면 UPDATE를 수행하십시오. INSERT를 시도하여 중복 키를 누르면 일부 클라이언트 인터페이스에서 예외로 변환되는 오류가 생성됩니다. MySQL에서 이것을 수행하는 단점은 INSERT가 실패하더라도 새로운 자동 증가 ID를 생성한다는 것입니다. 그래서 당신은 갭을 갖게됩니다. 자동 증가 시퀀스의 갭이 일반적으로 걱정할 사항이 아니라는 사실을 알고 있습니다. 그러나이 효과로 인해 성공적인 삽입 사이에 1000-1500의 갭을 가진 고객을 작년에 도왔습니다. 그 결과는 고객이 기본 키에 INT.

@baraky에 따르면, 먼저 UPDATE를 시도 할 수 있으며, 0 행에 영향을주는 경우 INSERT를 대신 수행 할 수 있습니다. 이 전략에 대한 제 의견은 제로 행을 UPDATE하는 것이 예외는 아니므로 UPDATE 후에 "성공한 행 수"를 확인하여 성공했는지 여부를 확인해야합니다.

그러나 영향을받는 행 수를 쿼리하면 원래 문제로 돌아갑니다. MySQL에서 HSQLDB와는 다른 쿼리를 사용해야합니다.

HSQLDB :

CALL DIAGNOSTICS(ROW_COUNT); 

MySQL은 :

SELECT ROW_COUNT(); 
+0

또는 INSERT를 수행하고 SQLException을 catch 한 다음 무결성 제약 조건 위반 인 경우 업데이트를 수행하십시오. – fredt

+0

사실 그것은 (거의) 내가 할 일입니다. - 업데이트 할 것이고 예외를 잡을 것입니다. 나를) 삽입하고 실패하면 삽입하십시오. 고맙습니다! – BobTheBuilder

3

단일 명령에 upsert을 수행하는 신택스는 RDBMS로 변한다.

는 MySQL의에서 그 다음 여러 명령을 사용해야합니다, 당신은 크로스 플랫폼 솔루션을 원하는 경우가 MERGE

있어 HSQLDB에서 INSERT...ON DUPLICATE KEY UPDATE

을합니다. 먼저 기존 행을 확인한 다음 필요에 따라 조건부로 삽입 또는 업데이트하십시오.

+0

여러 명령을 사용하고 싶지는 않습니다. 다른 테스트 방법과 dev가 동일한 코드를 실행하는 방법은 무엇입니까? – BobTheBuilder

+0

조건 코드를 사용하여 수행하는 것이 좋습니다. 그렇게하지 않으려면 테스트를 표준화하고 dev 환경에서 동일한 RD 사용 BMS. –

+0

@baraky : 여러 DBMS를 지원하려면 모든 DBMS에서 실행되는 문으로 모든 문제를 해결할 수 없습니다. DBMS 관련 성명서를 준비하십시오. 다른 모든 것은 실패 할 것입니다. –