Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android.database.sqlite.SQLiteConstraintException:唯一约束失败_Android_Sqlite - Fatal编程技术网

android.database.sqlite.SQLiteConstraintException:唯一约束失败

android.database.sqlite.SQLiteConstraintException:唯一约束失败,android,sqlite,Android,Sqlite,当我想向sqlite添加数据时,会弹出此错误。以前在SQLite中已经有一个数据。你能帮我解决我的问题吗? 为什么在设置id自动递增时插入id 删除args.put(ID_MOVIE,movieFavorite.getId())来自插入查询,如下所示 public long insertMovie(MovieFav movieFavorite) { ContentValues args = new ContentValues(); args.put(TITLE,

当我想向sqlite添加数据时,会弹出此错误。以前在SQLite中已经有一个数据。你能帮我解决我的问题吗?


为什么在设置id自动递增时插入id
删除args.put(ID_MOVIE,movieFavorite.getId())来自插入查询,如下所示

public long insertMovie(MovieFav movieFavorite) {
        ContentValues args = new ContentValues();
        args.put(TITLE, movieFavorite.getTitle());
        args.put(OVERVIEW, movieFavorite.getOverview());
        args.put(RELEASE_DATE, movieFavorite.getRelease_date());
        args.put(VOTE_AVERAGE, movieFavorite.getVote_average());
        args.put(POSTER_PATH, movieFavorite.getPoster_path());
        return sqLiteDatabase.insert(DATABASE_TABLE, null, args);
    }

您可能不希望有这样一行:-

args.put(ID_MOVIE, movieFavorite.getId());
插入电影方法中

如果没有该行,将自动生成id(1、2、3(可能))

如果确实包含了上述行,则会尝试插入,但如果该值已在该列的其他行中使用,则会出现唯一约束冲突。也就是说,主键必须是唯一的,因此即使没有编码唯一,它们也是唯一的,就好像编码唯一一样(即暗示了唯一约束)

注;您很可能不需要自动递增
+”(%s INTEGER主键,++
仍将自动生成id,但效率更高。根据:-

AUTOINCREMENT关键字会带来额外的CPU、内存、磁盘空间和磁盘I/O开销,如果不严格需要,应该避免使用。通常不需要

根据评论:-

如果未添加args.put(ID_MOVIE,movieFavorite.getId()),则数据将被复制

下面是一个例子:-

DbHelper.java 活动中的代码 日志中的结果:- 如上所述,始终尝试添加4行,如果再次运行,则:-

2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is Gone with the wind
        ID is 1
        Overview is 
            It blows
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Magnificent Seven
        ID is 2
        Overview is 
            Magnificent
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Lord of the Rings
        ID is 3
        Overview is 
            I'll ring you about this one
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is War of the Worlds
        ID is 4
        Overview is 
            Alien to me
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is Gone with the wind
        ID is 5
        Overview is 
            It blows
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Magnificent Seven
        ID is 6
        Overview is 
            Magnificent
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Lord of the Rings
        ID is 7
        Overview is 
            I'll ring you about this one
2019-09-28 20:00:52.455 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is War of the Worlds
        ID is 8
        Overview is 
            Alien to me
i、 e.添加了相同的行,但有其他id(这次为5-8)

没有重复的电影 如果您想要的是不复制数据,比如整个电影,这样就不会添加5-8,那么您可以创建一个适用于您不想复制的数据的唯一约束。id将永远不会被复制。从电影信息的角度来看,就数据而言,它不能也没有用处(从数据库的角度来看,id非常有用)

如果已经有一部电影具有相同的标题和相同的发行日期,则假设您永远不希望添加电影,那么您可以使电影标题和电影发行日期的组合唯一

e、 g.对于上述内容,您创建表格的代码可以是(见注释):-

  • 请注意,
    Log.d(“ALTINSERTSQL”,sqlstmnt.toString());
    行是不需要的,添加它是为了显示SQL生成的内容,如传递给SQLite的内容

  • 在电影(标题、概述、发行日期、投票平均数、照片)中插入或忽略值(?、、?、?)

  • 's由SQLite API绑定(与使用String.format类似),因此使用bindallargsassstrings允许SQLite将每个?替换为适当的值。这会阻止SQLInjection

考虑上述情况并使用:-

    mMyDBHlpr = new DbHelper(this); //Instantiate Database Helper

    // Add some Movies WITHOUT specifying ID
    mMyDBHlpr.insertMovie(new MovieFav("Gone with the wind","It blows","2019-01-01","medium","//posters/movies/gwtw"));
    mMyDBHlpr.insertMovie(new MovieFav("The Magnificent Seven","Magnificent","2019-10-01","medium","//posters/movies/tms"));
    mMyDBHlpr.insertMovie(new MovieFav("The Lord of the Rings","I'll ring you about this one","2015-12-01","great","//posters/movies/lotrp1"));
    mMyDBHlpr.insertMovie(new MovieFav("War of the Worlds","Alien to me","2010-01-01","ok","//posters/movies/wotw"));

    mMyDBHlpr.insertMovieAlternative(new MovieFav("Gone with the wind","It blows","2019-01-01","medium","//posters/movies/gwtw"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("The Magnificent Seven","Magnificent","2019-10-01","medium","//posters/movies/tms"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("The Lord of the Rings","I'll ring you about this one","2015-12-01","great","//posters/movies/lotrp1"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("War of the Worlds","Alien to me","2010-01-01","ok","//posters/movies/wotw"));

    // Output Movies information to the log INCLUDING ID
    mMyDBHlpr.logAllMovies();
这会尝试添加同一组电影,但第二批不会添加,因为为电影标题Moview发行日期组合添加了唯一约束,但日志中不包含异常消息(没有异常,因为如果发生冲突,INSERT或IGNORE将充当noop(不执行任何操作))

日志将改为:-

2019-09-28 20:52:06.304 D/ALTINSERTSQL: SQLiteProgram: INSERT OR IGNORE INTO movie(title,overview,release_date,vote_average,photo) VALUES (?,?,?,?,?)
2019-09-28 20:52:06.305 I/chatty: uid=10419(aso.asoinmemorysbtofiledb) identical 2 lines
2019-09-28 20:52:06.306 D/ALTINSERTSQL: SQLiteProgram: INSERT OR IGNORE INTO movie(title,overview,release_date,vote_average,photo) VALUES (?,?,?,?,?)
2019-09-28 20:52:06.307 D/MOVIELIST: Title is Gone with the wind
        ID is 1
        Overview is 
            It blows
2019-09-28 20:52:06.307 D/MOVIELIST: Title is The Magnificent Seven
        ID is 2
        Overview is 
            Magnificent
2019-09-28 20:52:06.307 D/MOVIELIST: Title is The Lord of the Rings
        ID is 3
        Overview is 
            I'll ring you about this one
2019-09-28 20:52:06.307 D/MOVIELIST: Title is War of the Worlds
        ID is 4
        Overview is 
            Alien to me

如果未添加args.put(ID\u MOVIE,movieFavorite.getId()),则数据将被复制。如果args.put(ID\u MOVIE,movieFavorite.getId())如果不添加;,则数据将被复制。@SatyaRac如果不提供值,即no
args.put
,则基础SQL将不提供值,并且由于该列是rowid列的别名,则该值将自动生成并唯一。根据插入,如果rowid或INTEGER主键列不显式如果给定一个值,则该值将自动填充一个未使用的整数,通常比当前使用的最大ROWID多一个。无论是否使用AUTOINCREMENT关键字,这都是正确的。@SatyaRac,我相信我现在理解了,希望答案的其他部分能够解决这些问题(简而言之,这并不是真正的问题,这些消息只是由于异常被捕获、处理和报告而没有添加和产生重复项的信息)。
public class MainActivity extends AppCompatActivity {

    DbHelper mMyDBHlpr;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyDBHlpr = new DbHelper(this); //Instantiate Database Helper

        // Add some Movies WITHOUT specifying ID
        mMyDBHlpr.insertMovie(new MovieFav("Gone with the wind","It blows","2019-01-01","medium","//posters/movies/gwtw"));
        mMyDBHlpr.insertMovie(new MovieFav("The Magnificent Seven","Magnificent","2019-10-01","medium","//posters/movies/tms"));
        mMyDBHlpr.insertMovie(new MovieFav("The Lord of the Rings","I'll ring you about this one","2015-12-01","great","//posters/movies/lotrp1"));
        mMyDBHlpr.insertMovie(new MovieFav("War of the Worlds","Alien to me","2010-01-01","ok","//posters/movies/wotw"));
        // Output Movies information to the log INCLUDING ID
        mMyDBHlpr.logAllMovies();

    }
2019-09-28 19:51:52.242 7088-7088/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is Gone with the wind
        ID is 1
        Overview is 
            It blows
2019-09-28 19:51:52.243 7088-7088/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Magnificent Seven
        ID is 2
        Overview is 
            Magnificent
2019-09-28 19:51:52.243 7088-7088/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Lord of the Rings
        ID is 3
        Overview is 
            I'll ring you about this one
2019-09-28 19:51:52.243 7088-7088/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is War of the Worlds
        ID is 4
        Overview is 
            Alien to me
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is Gone with the wind
        ID is 1
        Overview is 
            It blows
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Magnificent Seven
        ID is 2
        Overview is 
            Magnificent
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Lord of the Rings
        ID is 3
        Overview is 
            I'll ring you about this one
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is War of the Worlds
        ID is 4
        Overview is 
            Alien to me
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is Gone with the wind
        ID is 5
        Overview is 
            It blows
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Magnificent Seven
        ID is 6
        Overview is 
            Magnificent
2019-09-28 20:00:52.454 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is The Lord of the Rings
        ID is 7
        Overview is 
            I'll ring you about this one
2019-09-28 20:00:52.455 7188-7188/aso.asoinmemorysbtofiledb D/MOVIELIST: Title is War of the Worlds
        ID is 8
        Overview is 
            Alien to me
private static  final String DATABASE_NAME = "movielist";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_TABLE = DbContract.TABLE_MOVIE;
private static final String SQL_CREATE_TABLE_MOVIE_FAV = String.format("CREATE TABLE %s"
        + " (%s INTEGER PRIMARY KEY AUTOINCREMENT," +
        " %s TEXT NOT NULL," +
        " %s TEXT NOT NULL," +
        " %s TEXT NOT NULL," +
        " %s TEXT NOT NULL," +
        " %s TEXT NOT NULL" + //<<<<<<<<<< REMOVED CLOSING PARENTHESIS
        /* ADDED the UNQIUE CONSTRAINT ON THE Title and release date */
                ", UNIQUE ("
                + DbContract.MovieListFavorite.MOVIE_TITLE +
                "," + DbContract.MovieListFavorite.MOVIE_RELEASE_DATE
                + ")" + // END Of THE UNIQUE CONSTRAINT
                ")", //<<<<<<<<<< END OF CHANGES FOR ADDING UNIQUE constraint
        /**
         * NOTE AS THE SCHEMA HAS CHANGED THE DATABASE NEEDS TO BE DELETED (altering is possible but harder)
         * THEREFORE TO INTRODUCE CHANGES >>>>>>>>>>UNINSTALL THE APP AND THEN RERUN<<<<<<<<<<.
         */
        DATABASE_TABLE,
        DbContract.MovieListFavorite.MOVIE_ID,
        DbContract.MovieListFavorite.MOVIE_TITLE,
        DbContract.MovieListFavorite.MOVIE_OVERVIEW,
        DbContract.MovieListFavorite.MOVIE_RELEASE_DATE,
        DbContract.MovieListFavorite.MOVIE_PHOTO,
        DbContract.MovieListFavorite.MOVIE_VOTE_AVERAGE
);
public long insertMovieAlternative(MovieFav movieFavorite) {
    String insertSQL = "INSERT OR IGNORE INTO " + DATABASE_TABLE +
            "(" +
            DbContract.MovieListFavorite.MOVIE_TITLE + "," +
            DbContract.MovieListFavorite.MOVIE_OVERVIEW + "," +
            DbContract.MovieListFavorite.MOVIE_RELEASE_DATE + "," +
            DbContract.MovieListFavorite.MOVIE_VOTE_AVERAGE + "," +
            DbContract.MovieListFavorite.MOVIE_PHOTO +
            ") VALUES (?,?,?,?,?)";
    SQLiteStatement sqlstmnt = sqLiteDatabase.compileStatement(insertSQL);
    sqlstmnt.bindAllArgsAsStrings(new String[]{
            movieFavorite.getTitle(),
            movieFavorite.getOverview(),
            movieFavorite.getRelease_date(),
            movieFavorite.getVote_average(),
            movieFavorite.getPoster_path()
    });
    Log.d("ALTINSERTSQL",sqlstmnt.toString());
    return sqlstmnt.executeInsert();
}
    mMyDBHlpr = new DbHelper(this); //Instantiate Database Helper

    // Add some Movies WITHOUT specifying ID
    mMyDBHlpr.insertMovie(new MovieFav("Gone with the wind","It blows","2019-01-01","medium","//posters/movies/gwtw"));
    mMyDBHlpr.insertMovie(new MovieFav("The Magnificent Seven","Magnificent","2019-10-01","medium","//posters/movies/tms"));
    mMyDBHlpr.insertMovie(new MovieFav("The Lord of the Rings","I'll ring you about this one","2015-12-01","great","//posters/movies/lotrp1"));
    mMyDBHlpr.insertMovie(new MovieFav("War of the Worlds","Alien to me","2010-01-01","ok","//posters/movies/wotw"));

    mMyDBHlpr.insertMovieAlternative(new MovieFav("Gone with the wind","It blows","2019-01-01","medium","//posters/movies/gwtw"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("The Magnificent Seven","Magnificent","2019-10-01","medium","//posters/movies/tms"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("The Lord of the Rings","I'll ring you about this one","2015-12-01","great","//posters/movies/lotrp1"));
    mMyDBHlpr.insertMovieAlternative(new MovieFav("War of the Worlds","Alien to me","2010-01-01","ok","//posters/movies/wotw"));

    // Output Movies information to the log INCLUDING ID
    mMyDBHlpr.logAllMovies();
2019-09-28 20:52:06.304 D/ALTINSERTSQL: SQLiteProgram: INSERT OR IGNORE INTO movie(title,overview,release_date,vote_average,photo) VALUES (?,?,?,?,?)
2019-09-28 20:52:06.305 I/chatty: uid=10419(aso.asoinmemorysbtofiledb) identical 2 lines
2019-09-28 20:52:06.306 D/ALTINSERTSQL: SQLiteProgram: INSERT OR IGNORE INTO movie(title,overview,release_date,vote_average,photo) VALUES (?,?,?,?,?)
2019-09-28 20:52:06.307 D/MOVIELIST: Title is Gone with the wind
        ID is 1
        Overview is 
            It blows
2019-09-28 20:52:06.307 D/MOVIELIST: Title is The Magnificent Seven
        ID is 2
        Overview is 
            Magnificent
2019-09-28 20:52:06.307 D/MOVIELIST: Title is The Lord of the Rings
        ID is 3
        Overview is 
            I'll ring you about this one
2019-09-28 20:52:06.307 D/MOVIELIST: Title is War of the Worlds
        ID is 4
        Overview is 
            Alien to me