2016-09-28 14 views
1

node-sqlite3을 사용하여 node.js 응용 프로그램의 데이터베이스에서 INSERT + UPDATE 트랜잭션을 수행하려고합니다. 그러나, 나는 트랜잭션이 완료되면 last_insert_rowid를 얻는 방법을 알아낼 수 없다.트랜잭션에서 last_insert_rowid를 가져 오는 방법은 무엇입니까?

BEGIN TRANSACTION; 
    INSERT INTO <table> (field1, ...) VALUES (value1, ...); 
    UPDATE <table> SET prev=last_insert_rowid() WHERE <condition>; 
END TRANSACTION; 

이 문자열 (마이너스 여분의 공백이) VAR q에 할당 : 내 쿼리는 다음과 같이 보입니다. ,

db.run(q, function(err) { 
    if (err) ... 
    console.log(this.lastId) 
}) 

을뿐만 아니라 그것은 오류없이 "0"인쇄 않습니다

내 데이터베이스를 사용하여이 어떤 점에서 열이있어 :

var db = new sqlite3.Database(dbfile) 

을하지만 사용하려고하면 데이터베이스에 대한 변경은 발생하지 않습니다 !!! run 대신 exec을 사용하면 쿼리가 성공적으로 실행되지만 exec에서 데이터를 다시 얻을 수있는 방법이 없습니다.

나는 또한 시도 이런 식으로 뭔가 :

db.exec(q, function(err) { 
    if (err) ... 
    db.run(";", function(err) { 
     if (err) ... 
     console.log(this.lastId) 
    }) 
}) 

그러나 "실행"에서 "이"상황은 lastId 속성이 없습니다!

또한 sqlite3-transaction 패키지를 살펴 보았지만 트랜잭션 콜백 중 어떤 정보도 제공하지 않는 것 같습니다!

삽입을 별도의 run()으로 실행할 수없고 this.lastId을 얻은 다음 해당 업데이트를 사용하면 데이터베이스가 두 문장 사이에 유효하지 않은 상태로 남게됩니다 (따라서 트랜잭션).

이 트랜잭션에서 last_insert_rowid()를 얻으려면 어떻게해야합니까?

+0

궁금한 점이 있지만 MySQL에서 가장 최근에 삽입 된 ID를 가져 오는 기능은 일부 사전 조건이 충족 될뿐만 아니라 사용중인 드라이버 (예 : Perl + DBI' +'DBD :: mysql' 모듈)에 따라 달라질 수 있습니다 예를 들어, 테이블 ID가 자동 증가로 설정된 정수 PK 여야합니다. 특정 상황에서 유사/다른 요구 사항을 적용 할 수 있는지 확인 했습니까? 또한 어떤 쿼리가 마지막으로 실행되었는지에 따라 달라질 수 있으므로 실제 트랜잭션의 컨텍스트에서이를 수행 할 수 있는지 확인해야 할 수도 있습니다. – ray

+0

'run'을 별도로 호출하여 트랜잭션을 사용할 수 있습니다. 'run ("BEGIN TRANSACTION", ...)'등을 호출하고 작업이 완료되면'COMMIT TRANSACTION'을 호출하십시오. 에러가 발생하면'ROLLBACK TRANSACTION'을 호출하십시오. – cartant

+0

@cartant 감사합니다. 나는 어제 떠나야 만하기 전에 실제로 그것을 발견하고 성공적으로 시도했지만, 아직 문서화되지 않았습니다. – Michael

답변

0

last_insert_rowid()를 얻으려면 다음과 같이 트랜잭션을 조각으로 분할해야합니다. 콜백의 ROWID를 받고,

db.run("BEGIN TRANSACTION") 

다음 행을 삽입하는 명령을 실행합니다 : 첫째, 트랜잭션을 시작하는 쿼리를 실행

// replace stuff in angle brackets and ellipses with proper values 
db.run("INSERT INTO <table> (field1, ...) VALUES (value1, ...);", function(err,data) { 
    if (err) ... 
    rowid=this.lastID // rowid declared in scope visible outside callback 
}) 

다음으로, 업데이트를 실행합니다. 트랜잭션이 아직 커밋되지 않았으므로 이러한 콜백은 아직 호출되지 않습니다. 업데이트가 트랜잭션의 마지막 문장이기 때문에 그것은 전체 트랜잭션이 성공해야 성공하면,이 경우

db.run("END TRANSACTION;") 

, 그래서 할 안전합니다 :

db.run("UPDATE <table> SET prev=last_insert_rowid() WHERE <condition>;", function(err,data) { 
    // do whatever needs doing after update is done here 
}) 

이제 트랜잭션을 커밋 그 곳에서 거래 후에해야 할 일이 무엇이든간에