문제

신뢰할 수 있는 방법이 있는지 찾으려고 노력 중입니다. SQLite) 삽입할 다음 행의 ID를 찾으려면, 삽입되기 전에.다른 삽입 문에 ID를 사용해야 하지만 즉시 삽입하고 다음 행을 가져오는 옵션이 없습니다.

다음 ID를 예측하는 것은 마지막 ID를 가져와 추가하는 것만큼 간단합니까?그게 보증인가요?

편집하다:좀 더 추론을 해보자면...삽입이 사용자에 의해 취소될 수 있으므로 즉시 삽입할 수 없습니다.사용자는 몇 가지 사항을 변경하고 SQL 문이 저장되며 거기에서 저장(모든 행을 한 번에 삽입)하거나 취소(아무 것도 변경하지 않음)할 수 있습니다.프로그램 충돌이 발생하는 경우 원하는 기능은 아무것도 변경되지 않는 것입니다.

도움이 되었습니까?

해결책

일련의 데이터베이스 작업을 한 번에 폐기하거나 커밋하는 것이 바로 트랜잭션의 목적입니다.질문 BEGIN; 사용자가 조작을 시작하기 전에 COMMIT; 그/그녀가 끝나면.모든 변경 사항이 적용되거나(커밋하는 경우) 모든 것이 폐기됩니다(쿼리하는 경우). ROLLBACK;, 프로그램이 충돌하면 전원이 꺼지는 등).DB에서 읽으면 트랜잭션이 끝날 때까지 데이터가 양호하다는 것을 보장하므로 데이터를 가져올 수 있습니다. MAX(id) 또는 경쟁 조건에 대해 걱정하지 않고 원하는 무엇이든 가능합니다.

http://www.sqlite.org/lang_transaction.html

다른 팁

노력하다 SELECT * FROM SQLITE_SEQUENCE WHERE name='TABLE';.여기에는 다음과 같은 필드가 포함됩니다. seq 이는 선택한 테이블에서 가장 큰 숫자입니다.다음 ID를 얻으려면 이 값에 1을 더하세요.

또한 SQLite 자동 증가 기사, 위의 정보가 나온 곳입니다.

건배!

반환된 값에 1을 더하면 문제가 해결될 수 있습니다. sqlite3_last_insert_rowid 예를 들어 동일한 데이터베이스 연결을 사용하고 다른 동시 작성자가 없는 특정 조건에서.물론 이러한 가정을 뒷받침하기 위해 sqlite 소스 코드를 참조할 수도 있습니다.

그러나 다음 ID를 예측할 필요가 없는 다른 접근 방식을 사용하는 것을 진지하게 고려할 수도 있습니다.사용 중인 sqlite 버전에 맞게 설정하더라도 나중에 상황이 바뀔 수 있으며 이로 인해 확실히 다른 데이터베이스로 이동하는 것이 더 어려워질 것입니다.

일종의 INVALID 플래그가 있는 행을 삽입하고, ID를 가져오고, 필요에 따라 편집하고, 필요한 경우 삭제하거나 유효한 것으로 표시합니다.그러면 시퀀스의 공백에 대해 걱정하지 마세요.

그런데, 유효하지 않은 부분을 직접 수행하는 방법을 알아내야 합니다.세부 사항에 따라 무언가를 NULL로 표시하는 것이 작동할 수 있습니다.

편집하다: 가능하다면 적절한 거래를 사용하라는 Eevee의 제안을 사용하십시오.작업량이 훨씬 적습니다.

SQLite를 사용하는 애플리케이션은 규모가 작고 SQLite에는 고유한 의미가 있다는 것을 알고 있습니다.여기에 게시된 다른 솔루션은 이 특정 설정에서 원하는 효과를 가질 수도 있지만, 내 생각에는 지금까지 읽은 모든 솔루션은 근본적으로 올바르지 않으며 피해야 합니다.

일반적인 환경에서는 사용자 입력을 위한 트랜잭션을 보유하는 것을 어떤 대가를 치르더라도 피해야 합니다.중간 데이터를 저장해야 하는 경우 이를 처리하는 방법은 이 목적을 위해 스크래치 테이블에 정보를 쓴 다음 원자성 트랜잭션에서 모든 정보를 쓰려고 시도하는 것입니다.트랜잭션을 보류하면 다중 사용자 환경에서 교착 상태와 동시성 악몽이 발생합니다.

대부분의 환경에서는 트랜잭션 내에서 SELECT를 통해 검색된 데이터가 반복 가능하다고 가정할 수 없습니다.예를 들어

SELECT Balance FROM Bank ...
UPDATE Bank SET Balance = valuefromselect + 1.00 WHERE ...

UPDATE 후에 잔액 값이 변경될 수 있습니다.때로는 거래 내에서 Bank에 관심 있는 행을 먼저 업데이트하여 이 문제를 해결할 수 있습니다. 이는 거래가 완료될 때까지 추가 업데이트가 값을 변경하지 못하도록 행을 잠그는 것을 보장하기 때문입니다.

그러나 이 경우 일관성을 보장하는 더 좋은 방법은 업데이트의 WHERE 절에 있는 데이터 내용에 대한 가정을 확인하고 애플리케이션의 행 수를 확인하는 것입니다.위의 예에서 "은행 업데이트"를 수행할 때 WHERE 절은 예상되는 현재 잔액 값을 제공해야 합니다.

WHERE Balance = valuefromselect

예상 잔액이 더 이상 일치하지 않으면 WHERE 조건도 일치하지 않습니다. UPDATE는 아무 작업도 수행하지 않고 rowcount는 0을 반환합니다.이는 동시성 문제가 있음을 나타내며 다른 항목이 동시에 데이터를 변경하려고 시도하지 않는 경우 작업을 다시 실행해야 함을 나타냅니다.

select max(id) from particular_table is unreliable for the reason below..

http://www.sqlite.org/autoinc.html

"위에 설명된 일반 ROWID 선택 알고리즘은 최대 ROWID 값을 사용하지 않고 가장 큰 ROWID가 있는 테이블의 항목을 삭제하지 않는 한 단조롭게 증가하는 고유 ROWID를 생성합니다.행을 삭제하거나 가능한 최대 ROWID가 있는 행을 생성하는 경우 새 행을 생성할 때 이전에 삭제된 행의 ROWID가 재사용될 수 있으며 새로 생성된 ROWID는 엄밀히 말하면 오름차순이 아닐 수 있습니다.

나는 당신이 묻는 것과 삽입하는 사이에 아무것도 삽입되지 않을 것이라고 확신할 수 있는 방법이 없기 때문에 이것이 이루어질 수 없다고 생각합니다.(삽입을 위해 테이블을 잠글 수도 있지만 윽)

그런데 저는 MySQL만 사용해 봤지만 별 차이가 없을 것 같아요)

아마도 가장 최근의 ID를 +1할 수 있을 것입니다.나는 주문한 테이블에 있는 기존 ID를 모두 (잠깐 뒤로 돌아가서) 살펴보겠습니다.일관성이 있고 각 행의 ID가 마지막 것보다 1 더 많은가요?그렇다면 아마 괜찮을 것입니다.그러나 가정을 설명하는 주석을 코드에 남길 것입니다.잠금을 수행하면 이 작업을 수행하는 동안 추가 행을 얻지 못하게 되는 데 도움이 됩니다.

last_insert_rowid() 값을 선택합니다.

이 주제에서 말해야 할 대부분의 내용은 이미... 그러나 경쟁 조건에 매우 주의하십시오. 이 일을 할 때.두 사람이 모두 귀하의 애플리케이션/웹 페이지 등을 열고 그 중 한 명이 행을 추가하면 다른 사용자는 동일한 ID를 가진 행을 삽입하려고 시도할 것이며 많은 문제가 발생할 것입니다.

select max(id) from particular_table;

다음 ID는 최대 ID에서 +1이 됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top