如何避免Android中SQLite数据库中的重复行?

问题描述

我被困在如何避免 sqlite 数据库中的重复行。我在 StackOverflow 上尝试了所有可能的答案,但没有一个我有用。我尝试使用唯一约束 db.insertWithOnConflict() 但它们都没有采用。 任何人都可以帮我找出我的错误吗? 这是我的 Android 工作室的代码

Params.java:

public class Params {
public static final int DB_VERSION=1;
public static final String DB_NAME="PDF_NAME";
public static final String TABLE_NAME="PDF_TABLE";

public static final String KEY_ID="ID";
public static final String KEY_NAME="NAME";
public static final String KEY_PAGE="PAGE";

}

MyDbHandler.java

public class MyDbHandler extends sqliteOpenHelper {
  public static sqliteDatabase database;
public MyDbHandler(Context context) {
    super(context,Params.DB_NAME,null,Params.DB_VERSION);
}

@Override
   public void onCreate(sqliteDatabase db) {
    String create="CREATE TABLE "+Params.TABLE_NAME+"("+Params.KEY_ID+" INTEGER PRIMARY KEY,"+Params.KEY_NAME+" TEXT UNIQUE,"
            +Params.KEY_PAGE+" INTEGER"+")";
    db.execsql(create);
}

@Override
public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {

}
public void addPDF(File file)
{
    sqliteDatabase db=this.getWritableDatabase();
    ContentValues values=new ContentValues();
    values.put(Params.KEY_NAME,file.getName());
    values.put(Params.KEY_PAGE,ViewPdf.pagenumber);
    db.insertWithOnConflict(Params.TABLE_NAME,values,sqliteDatabase.CONFLICT_REPLACE);
    Log.d("pa","pagenumber"+file.getName() + ViewPdf.pagenumber);
    Log.d("data","Inserted");
    db.close();

}
public Cursor getALlfile()
{
    database=this.getReadableDatabase();
    String select="SELECT * FROM "+Params.TABLE_NAME;
    Cursor cursor=database.rawQuery(select,null);
   return cursor;
 }


}

DocumentsFragment.java:

 public void onItemClick(int position) {

    Intent intent = new Intent(getContext(),ViewPdf.class);
    intent.putExtra("Position",position);
    startActivity(intent);
    if (!HistoryFragment.pdfHistory.contains(pdf.get(position))) {
        HistoryFragment.pdfHistory.add(0,pdf.get(position));
    } else {
        File newpdf = pdf.get(position);
        int pos = HistoryFragment.pdfHistory.indexOf(newpdf);
        HistoryFragment.pdfHistory.remove(pos);
        HistoryFragment.pdfHistory.add(0,newpdf);
    }
     Cursor cursor=MyDbHandler.database.rawQuery("Select * from" + Params.TABLE_NAME + "where"+Params.KEY_NAME+ "=" +(pdf.get(position).getName()),null);
    if(cursor.movetoFirst())
        Toast.makeText(getContext(),"already exist",Toast.LENGTH_SHORT).show();
    else{
       db.addPDF(pdf.get(position));
    }

如果有任何用处,我也附上我的 logcat:

更新

     2021-05-08 17:54:15.181 11873-11873/com.flashxpdfreader.flash2021 E/sqliteLog: (1) no such column: ghty.pdf
2021-05-08 17:54:15.182 11873-11873/com.flashxpdfreader.flash2021 D/AndroidRuntime: Shutting down VM
2021-05-08 17:54:15.183 11873-11873/com.flashxpdfreader.flash2021 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.flashxpdfreader.flash2021,PID: 11873
    android.database.sqlite.sqliteException: no such column: ghty.pdf (code 1 sqlITE_ERROR):,while compiling: Select * from PDF_TABLE where NAME = ghty.pdf
        at android.database.sqlite.sqliteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.sqliteConnection.acquirePreparedStatement(sqliteConnection.java:986)
        at android.database.sqlite.sqliteConnection.prepare(sqliteConnection.java:593)
        at android.database.sqlite.sqliteSession.prepare(sqliteSession.java:590)
        at android.database.sqlite.sqliteProgram.<init>(sqliteProgram.java:61)
        at android.database.sqlite.sqliteQuery.<init>(sqliteQuery.java:37)
        at android.database.sqlite.sqliteDirectCursorDriver.query(sqliteDirectCursorDriver.java:46)
        at android.database.sqlite.sqliteDatabase.rawQueryWithFactory(sqliteDatabase.java:1443)
        at android.database.sqlite.sqliteDatabase.rawQuery(sqliteDatabase.java:1382)
        at com.flashxpdfreader.flash2021.Fragment.DocumentsFragment.onItemClick(DocumentsFragment.java:156)
        at com.flashxpdfreader.flash2021.RecylerAdapter$ViewHolder.lambda$new$0$RecylerAdapter$ViewHolder(RecylerAdapter.java:137)
        at com.flashxpdfreader.flash2021.-$$Lambda$RecylerAdapter$ViewHolder$8a1BheGsPwqyn4c_IFEij433NiM.onClick(UnkNown Source:2)
        at android.view.View.performClick(View.java:7185)
        at android.view.View.performClickInternal(View.java:7162)
        at android.view.View.access$3500(View.java:819)
        at android.view.View$PerformClick.run(View.java:27684)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7562)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

这是我的 sqlite 数据库浏览器的屏幕截图:

enter image description here

您可以注意到我的数据库中实际上有相同的文件名,但它仍然显示没有这样的列。

解决方法

ctrx_sync_on_window("Transfer Report {(##/##/## ##:##:##)}",ACTIVATE,7,1359,642,"snapshot33",CTRX_LAST);

目前你的sql语句是这样的:

android.database.sqlite.SQLiteException: near "fromPDF_TABLEwhereNAME": syntax error (code 1 SQLITE_ERROR):,while compiling: Select * fromPDF_TABLEwhereNAME=fhg.pdf

您需要添加空间。你的sql语句需要是这样的:

Select * fromPDF_TABLEwhereNAME=fhg.pdf

在 DocumentsFragment.java 中,尝试更改来自

的代码
Select * from PDF_TABLE where NAME = fhg.pdf

Cursor cursor=MyDbHandler.database.rawQuery("Select * from" + Params.TABLE_NAME + "where"+Params.KEY_NAME+ "=" +(pdf.get(position).getName()),null);
,

而是检查您的光标是否返回某些内容。如果 itemcount 为 != 0,则 pdf 存在。

Cursor cursor=MyDbHandler.database.rawQuery("Select * from " + Params.TABLE_NAME + " where "+Params.KEY_NAME+ "=" +(pdf.get(position).getName()),null);    
if(cursor.getCount() != 0)
    Toast.makeText(getContext(),"already exist",Toast.LENGTH_SHORT).show();
else{
   db.addPDF(pdf.get(position));
}