相关疑难解决方法(0)

SQLite - UPSERT*不*INSERT或REPLACE

http://en.wikipedia.org/wiki/Upsert

在SQL Server上插入更新存储过程

在SQLite中有没有一些我没想到的聪明方法?

基本上,如果记录存在,我想更新四列中的三列,如果它不存在,我想用第四列的默认(NUL)值插入记录.

ID是主键,因此UPSERT只会有一条记录.

(我试图避免SELECT的开销,以确定我是否需要更新或插入显然)

建议?


我无法在SQLite网站上确认SQL CREATE的语法.我还没有构建一个演示来测试它,但它似乎不支持..

如果是,我有三列,所以它实际上看起来像:

CREATE TABLE table1( 
    id INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
    Blob1 BLOB ON CONFLICT REPLACE, 
    Blob2 BLOB ON CONFLICT REPLACE, 
    Blob3 BLOB 
);
Run Code Online (Sandbox Code Playgroud)

但是前两个blob不会引起冲突,只有ID会因此我asusme Blob1和Blob2不会被替换(根据需要)


绑定数据时SQLite中的UPDATE是一个完整的事务,这意味着每个要更新的发送行都需要:Prepare/Bind/Step/Finalize语句,与允许使用重置函数的INSERT不同

语句对象的生命周期如下:

  1. 使用sqlite3_prepare_v2()创建对象
  2. 使用sqlite3_bind_接口将值绑定到主机参数.
  3. 通过调用sqlite3_step()运行SQL
  4. 使用sqlite3_reset()重置语句,然后返回步骤2并重复.
  5. 使用sqlite3_finalize()销毁语句对象.

更新我猜测与INSERT相比速度慢,但它与使用主键的SELECT相比如何呢?

也许我应该使用select来读取第4列(Blob3),然后使用REPLACE编写一条新记录,将原始的第4列与前3列的新数据混合在一起?

sql sqlite upsert

505
推荐指数
11
解决办法
28万
查看次数

房间更新(或插入,如果不存在)行和返回计数更改行

我需要更新,如果不存在,则插入行到ROOM DB.

我这样做: productRepository.updateProducts(productsResponse.getProductItems());

和:

@Override
public void updateProducts(final List<ProductItem> products) {
    new Thread(() -> {
        for (ProductItem item : products) {
            Product product = createProduct(item);
            productDao.insert(product);
        }
    }).start();
}
Run Code Online (Sandbox Code Playgroud)

在DAO中:

@Insert
void insert(Product products);
Run Code Online (Sandbox Code Playgroud)

但我有方法

@Update
void update(Product product);
Run Code Online (Sandbox Code Playgroud)

我有一些问题:

  1. 两种方法都是无效的.插入后如何返回保存的Product或boolean flag或insert count?

  2. 如果我试着打电话update而且我没有排它会插入吗?

  3. 如何更新(如果不是 - 插入)行和返回计数updatet或插入的行?

android android-room

21
推荐指数
5
解决办法
3万
查看次数

Android -room持久库 - DAO调用是异步的,因此如何获得回调?

从我所读的内容Room不允许您在主线程上发出数据库查询(因为可能导致主线程的延迟)). 所以想象一下,我正在尝试更新UI主线程上的textview哪些数据如何才能收到回调.让我举个例子.想象一下,我想将我的业务模型数据存储到一个名为Events的对象中.因此我们有一个EventDao对象:

想象我们在下面有这个DAO对象:

@Dao
public interface EventDao {

   @Query("SELECT * FROM " + Event.TABLE_NAME + " WHERE " + Event.DATE_FIELD + " > :minDate" limit 1)
   LiveData<List<Event>> getEvent(LocalDateTime minDate);

   @Insert(onConflict = REPLACE)
   void addEvent(Event event);

   @Delete
   void deleteEvent(Event event);

   @Update(onConflict = REPLACE)
   void updateEvent(Event event);

}
Run Code Online (Sandbox Code Playgroud)

现在在一些活动中,我有一个textview,我想更新它的值,所以我这样做:

 myTextView.setText(EventDao.getEvent(someDate));/*i think this is illegal as im trying to call room dao on mainthread, therefore how is this done correctly ? would i need to show a spinner while it updates ?*/ …
Run Code Online (Sandbox Code Playgroud)

android android-room

17
推荐指数
2
解决办法
2万
查看次数

带有延迟外键的 Android Room

我有几个定期从服务器更新的表 ( Benefit, Branch, Coupon) 和另外两个仅本地的表 ( FavoriteBenefit, UsedCoupon)。ER图如下所示: ER图

每当Benefit在服务器上删除a 时,我还想从FavoriteBenefit. 为此,我可以使用onDelete = ForeignKey.CASCADE,每当Benefit数据库中不再存在父级时,它FavoriteBenefit也会被删除。听起来不错。

每当我@Insert(onConflict = OnConflictStrategy.REPLACE)用来更新数据库中的好处时就会出现问题 。REPLACE实际上是一个执行DELETEINSERT,但DELETE在内部触发onDeleteFavoriteBenefit,因此,在该表中的所有数据被删除。

CouponUsedCoupon表也会出现类似的问题。)


我正在寻找一种方法来暂时禁用外键约束,直到事务结束。也就是说,不要在事务期间验证外键,而只在事务结束时验证。我仍然希望 Room 自动删除没有有效父级的实体。


似乎通过在定义上设置将外键标记为延迟应该完全符合我想要实现的目标。deferred = true@ForeignKey

布尔延迟 ()

外键约束可以推迟到事务完成。如果您在单个事务中对数据库进行批量插入,这将非常有用。默认情况下,外键约束是即时的,但您可以通过将此字段设置为 true 来更改它。

但即使我设置了deferred标志,它似乎也没有效果,因为FavoriteBenefit每次仍然被删除。

我是否deferred错误地理解了标志?

android foreign-keys deferred android-room

8
推荐指数
1
解决办法
1572
查看次数

标签 统计

android ×3

android-room ×3

deferred ×1

foreign-keys ×1

sql ×1

sqlite ×1

upsert ×1