在Android SQLite中我有一个表MyTable
。我在升级数据库后丢失了它。
如果可能的话,我该如何回滚掉落的桌子。
任何好的答案都会被接受。
谢谢。
删除表不是可恢复的操作,除非作为已回滚的事务的一部分执行(这似乎不是针对您的特定情况的方案)。
DROP TABLE语句删除使用CREATE TABLE语句添加的表。指定的名称是表名。
已删除的表将从数据库架构和磁盘文件中完全删除。该表无法恢复。与表关联的所有索引和触发器也将被删除。
这不是完整的图片,因为可以看到回滚事务下的行为(在https://sqliteonline.com/上测试):
drop table if exists paxtable;
create table paxtable (paxcolumn integer);
insert into paxtable values (42);
begin transaction;
drop table paxtable;
rollback;
select paxcolumn from paxtable;
这表明该表在回滚后仍然存在。如果你提交而不是回滚(或者如果你完全删除了交易控制),表已经死了,已经过期,去见了它的制造商,拖着这个致命的线圈,<在这里插入你最喜欢的比喻>。
因此,由于您没有将其作为回滚事务的一部分(事实上该表实际已经消失),您需要从头开始重新创建它(或者如果可能的话,从备份中重新创建它)。
澄清:
虽然您可以提交或回滚DML语句,例如“insert”或“delete”(如果您在事务中执行此操作),通常您不能回滚DDL语句,如“alter table”或“drop table”。
在大多数情况下,大多数数据库都是如此:Oracle,MSSQL,mySQL等。
sqlite有一个例外:如果你在事务中使用drop table
,那么rollback
将恢复该表。
否则(根据sqlite手册):
DROP TABLE语句删除使用CREATE TABLE语句添加的表。指定的名称是表名。已删除的表将从数据库架构和磁盘文件中完全删除。该表无法恢复。与表关联的所有索引和触发器也将被删除。
PS:
如果您对以下内容感兴趣,此链接将讨论“DDL”,“DML”和相关的首字母缩略词:
我认为对这个问题有两种不同的解释,我想确保两者得到回答并最终得到证明,因为这仍然是sqlite drop table rollback的最佳搜索结果(并且SQLite文档的链接似乎也具有误导性)。
对于第一个问题,您可以回滚在事务范围内发生的drop table DDL操作,即
// with connection created
var transaction = connection.BeginTransaction();
try {
// create a table
// drop a different table
transaction.Commit(); // go ahead and commit if everything is successfully
}
catch
{
transaction.Rollback(); // rollback in case of error
}
并且要确认这是与语言无关的相同行为,使用SQ Lite命令行shell时的行为相同:
sqlite3 demo
// outside transaction scope
create table tbl1( col varchar(10));
// list the current tables
.tables
// start a transaction that wraps both your DDL commands
begin transaction;
enter code here
create table tbl2 (col varchar(10));
drop table tbl1;
rollback;
.tables
期望最终的list tables
命令,仍然应该返回tbl1
,因为create table
和drop table
命令都被回滚。另一种说法是SQLite不受相同的DML / DDL限制,因为Oracle可以回滚哪些操作。
对于问题的第二种解释,即,我是否可以恢复在事务范围之外删除的表(这也会带来您作为开发人员和灾难恢复所具有的“Oh S#%T”体验),对SQ Lite文档的引用是合适的:
已删除的表将从数据库架构和磁盘文件中完全删除。该表无法恢复。与表关联的所有索引和触发器也将被删除。