在SQLite Android中使用相同的查询插入多个值

3

在我的应用程序中,经常需要向数据库表中插入许多值。

因此,我需要运行一个像这样的插入操作:

insert into clients 
(id, name, lastip, visites) values  
('20','John','1.1.1.1','0'),
('21','Kate','1.1.1.2','3'), 
('35','Phill','1.1.1.3','90') ;

我有两个关于SQL的问题(我是SQL的初学者)

  1. 如何避免主键冲突(如果尝试插入一个已存在的行,则替换其他列)导致崩溃?
  2. 是否有一种方法可以使用insert()方法或类似的SQLiteDatabase方法在同一查询中插入所有值,还是必须构建查询字符串并使用execSQL()

提前感谢。

2个回答

1

1.) 避免主键冲突的一种可能性是使用自动递增字段。

如果一个列具有类型INTEGER PRIMARY KEY AUTOINCREMENT,那么将使用稍微不同的ROWID选择算法。为新行选择的ROWID至少比以前在同一表中存在的最大ROWID大1。

请参阅sqlite文档此处

如果在您的示例中id是自动递增字段,则无需在插入中指定它。

2.) 是的,像您所引用的文档所说,这是可能的(对于一行):

public long insert (String table, String nullColumnHack, ContentValues values)

该映射包含行的初始列值。键应为列名,值应为列值。
但是,您应该使用预处理语句(参考此处:如何在Android中使用SQLite预处理语句?)。
如果您想一次性插入所有3行,则需要构建字符串或执行3次插入操作。
编辑您的评论:
3.) 这里已经有很好的答案了:INSERT IF NOT EXISTS ELSE UPDATE? 还请参见这里:http://sqlite.org/lang_conflict.html
当出现唯一约束冲突时,REPLACE算法会在插入或更新当前行之前删除导致约束冲突的现有行,并且命令会继续正常执行。如果发生NOT NULL约束冲突,则REPLACE冲突解决方案将使用该列的默认值替换NULL值,或者如果该列没有默认值,则使用ABORT算法。如果发生CHECK约束冲突,则REPLACE冲突解决方案始终像ABORT一样工作。

1
谢谢您的回答,我真的不想避免主键冲突,我需要的是如果已经存在,则更新行。 - Addev
@Adrmedi:我编辑了我的帖子,加入了更多与你问题相关的信息。 - fyr

1
如果您正在使用ContentProvider来访问数据库,则可以使用applyBatch()来执行此操作:
// List of operations
ArrayList<ContentProviderOperation) ops
    = new ArrayList<ContentProviderOperation>();

// Create the builder
ContentProviderOperation.Builder builder
    = ContentProviderOperation.newInsert(...);

// Create the first item
builder.withValue("Name", "John");
builder.withValue("IP", '1.1.1.1');
ops.add(builder.build());

// Create the second item
builder.withValue("Name", "Kate");
builder.withValue("IP", '1.1.1.2');
ops.add(builder.build());

// Insert the data as one transaction
getContentProvider().applyBatch("AUTHORITY", ops);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接