Android SQLite 삽입 또는 업데이트
설명서에서 볼 수 있듯이 삽입 또는 업데이트 구문은 다음 INSERT OR REPLACE INTO <table> (<columns>) VALUES (<values>)
과 같습니다 . 내 질문에 다음을 병합하는 함수가 있습니까?
public long insert (String table, String nullColumnHack, ContentValues values)
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
또는 준비된 SQL 문과 rawQuery를 사용하여 수행해야합니까?
Android에서 삽입 또는 업데이트를 수행하는 모범 사례는 무엇입니까?
한 번에 새 행 을 삽입하거나 기존 행 을 업데이트 하는 방법을 묻는다고 생각합니다 . 이 답변 에서 논의한 것처럼 단일 원시 SQL에서 가능하지만 충돌 알고리즘에 CONFLICT_IGNORE를 사용 하여 SQLiteDatabase.insertWithOnConflict ()를 사용하여 Android에서 두 단계로 수행하는 것이 더 쉽다는 것을 알았습니다 .
ContentValues initialValues = new ContentValues();
initialValues.put("_id", 1); // the execution is different if _id is 2
initialValues.put("columnA", "valueNEW");
int id = (int) yourdb.insertWithOnConflict("your_table", null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
if (id == -1) {
yourdb.update("your_table", initialValues, "_id=?", new String[] {"1"}); // number 1 is the _id here, update to variable for your code
}
이 예에서는 테이블 키가 "_id"열에 대해 설정되고 _id 레코드를 알고 있으며 이미 행 # 1 (_id = 1, columnA = "valueA", columnB = "valueB")이 있다고 가정합니다. CONFLICT_REPLACE 및 CONFLICT_IGNORE와 함께 insertWithOnConflict를 사용하는 차이점은 다음과 같습니다.
- CONFLICT_REPLACE는 다른 열의 기존 값을 null로 덮어 씁니다 (즉, columnB는 NULL이되고 결과는 _id = 1, columnA = "valueNEW", columnB = NULL이 됨). 결과로 기존 데이터를 잃고 내 코드에서 사용하지 않습니다.
- CONFLICT_IGNORE는 기존 행 # 1에 대한 SQL INSERT를 건너 뛰고 다른 모든 열의 내용을 유지하면서 다음 단계에서이 행을 SQL UPDATE합니다 (예 : 결과는 _id = 1, columnA = "valueNEW", columnB = "). valueB ").
아직 존재하지 않는 새 행 # 2를 삽입하려고하면 코드는 첫 번째 문 insertWithOnConflict에서만 SQL INSERT를 실행합니다 (즉, 결과는 _id = 2, columnA = "valueNEW", columnB = NULL이 됨).
SQLiteDatabase.CONFLICT_IGNORE가 API10 (및 아마도 API11)에서 오작동을 일으키는 이 버그에 주의하십시오 . Android 2.2에서 테스트 할 때 쿼리가 -1 대신 0을 반환합니다.
레코드 키 _id를 모르거나 충돌을 일으키지 않는 조건이있는 경우 논리를 UPDATE 또는 INSERT로 되돌릴 수 있습니다 . 그러면 UPDATE 중에 레코드 키 _id가 유지되거나 INSERT 중에 새 레코드 _id가 생성됩니다.
int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
위의 예에서는 예를 들어 레코드의 타임 스탬프 값을 UPDATE하려고한다고 가정합니다. insertWithOnConflict를 먼저 호출하면 INSERT는 타임 스탬프 조건의 차이로 인해 새 레코드 _id를 생성합니다.
이것은 SQLiteDatabase.insertWithOnConflict () 메서드 입니다. sqlite 에서이 문서 를 참조하는 것이 무엇인지 이해하기 위해
SQLiteDatabase.replace () 는이를 수행하며 기본적으로 다음을 호출합니다.
insertWithOnConflict(table, nullColumnHack, initialValues, CONFLICT_REPLACE);
문서가 너무 나쁘게 명확하지 않습니다.
이에 대한 작업 이름은 "upsert"이며이를 해결하는 방법은 행을 고유하게 만드는 테이블의 열을 식별하는 것입니다.
예 : _id, name, job, hours_worked
우리가 사용할 열은 이름과 직업입니다.
private int getID(String name, String job){
Cursor c = dbr.query(TABLE_NAME,new String[]{"_id"} "name =? AND job=?",new String[]{name,job},null,null,null,null);
if (c.moveToFirst()) //if the row exist then return the id
return c.getInt(c.getColumnIndex("_id"));
return -1;
}
데이터베이스 관리자 클래스에서 :
public void upsert(String name, String job){
ContentValues values = new ContentValues();
values.put("NAME",name);
values.put("JOB",job);
int id = getID(name,job);
if(id==-1)
db.insert(TABLE_NAME, null, values);
else
db.update(TABLE_NAME, values, "_id=?", new String[]{Integer.toString(id)});
}
SQLiteDatabase.replace() is probably what you are looking for. I haven't tried it but the doc says it returns the row ID of the newly inserted row, so it may work.
I had the same issue, but I realized when my object already has an Id it should be updated and when it does not have an Id it should be inserted so this is step by step what I did to resolve the issue:
1- in your object getId use Integer or initialize the Id how you see fit: here is my code
public Integer getId() {
return id;
}
2- check the Id in your method for insert or update after you put everything in ContentValues:
if(myObject.getId()!= null ){
int count = db.update(TABLE_NAME,myContentValues,ID + " = ? ",
new String[]{String.valueOf(myObject.getId())});
if(count<=0){
//inserting content values to db
db.insert(TABLE_NAME, null, myContentValues);
}
} else {
db.insert(TABLE_NAME, null, myContentValues);
}
what happens here is that I check for Id if does exist I update that row but if update method returns -1 it means there were no rows with that Id so I insert the row, and if it does not have an Id I insert it.
hope this helps.
What about replaceOrThrow(String table, String nullColumnHack, ContentValues initialValues)
Docs say... Convenience method for replacing a row in the database. Inserts a new row if a row does not already exist.
Basically it calls insertWithOnConflict
참고URL : https://stackoverflow.com/questions/13311727/android-sqlite-insert-or-update
'Program Tip' 카테고리의 다른 글
파이썬 함수에서 데코레이터를 제거하는 방법 (0) | 2020.12.10 |
---|---|
int 변수를 double로 변환해야합니다. (0) | 2020.12.10 |
matplotlib Python에서 다른 막대 색상 설정 (0) | 2020.12.10 |
bash 스크립트에서 찾기 결과를 어떻게 처리 할 수 있습니까? (0) | 2020.12.10 |
Linux 명령 줄을 사용하여 HTML 이메일을 보내는 방법 (0) | 2020.12.10 |