Android 如何处理基于更改的表名/列的sqlite触发器?
假设我有两个表和触发器:Android 如何处理基于更改的表名/列的sqlite触发器?,android,sqlite,triggers,android-sqlite,Android,Sqlite,Triggers,Android Sqlite,假设我有两个表和触发器: CREATE TABLE first_table ( `text` TEXT, `num` INTEGER, `id` INTEGER ); CREATE TABLE second_table ( `text` TEXT, `num` INTEGER, `id` INTEGER ); CREATE TRIGGER first_table_trigger AFTER INSERT ON first_table BEGIN INSERT INTO
CREATE TABLE first_table (
`text` TEXT,
`num` INTEGER,
`id` INTEGER
);
CREATE TABLE second_table (
`text` TEXT,
`num` INTEGER,
`id` INTEGER
);
CREATE TRIGGER first_table_trigger AFTER INSERT ON first_table
BEGIN
INSERT INTO second_table VALUES('NEW LINE', new.num, new.id);
END;
现在,假设我的android应用程序更改了第二个_表(添加了一列或将其名称更改为new_second_表
)。
现在,第一个\u表\u触发器无限期地失败!
我将如何从sql数据库处理此问题,而不必在应用程序代码中处理此问题
我的意思是,我能在第一个\u table\u触发器中动态猜测第二个表名或其列吗
我只需要sql/触发器的帮助,而不是代码:)
非常感谢。SQLite被设计成一个嵌入式数据库,与“真正的”编程语言一起使用
因此,它没有任何内置机制来创建动态SQL。
特别是,表名不能动态更改,但必须在每个SQL语句中逐字写入,并且在编译语句时(当实际使用触发器时),语句中提到的所有表名都必须存在。SQLite被设计为嵌入式数据库,与“真实”编程语言一起使用
因此,它没有任何内置机制来创建动态SQL。
特别是,表名不能动态更改,但必须在每个SQL语句中逐字写入,并且在编译语句时(实际使用触发器时),语句中提到的所有表名必须存在。如果您能够将数据库复制到SQLite管理工具(如SQLite Manager)中,我认为这需要一个根设备,或者应用程序有一种内置的方法,可以将数据库备份到一个可访问的存储位置,另外还可以从该存储位置的备份中恢复数据库
然后,您可以在复制数据库后在SQLite管理工具中手动修改该数据库,例如,删除并创建触发器,然后将数据库复制回设备的原始位置(如果设备是根设备),或者复制回使用具有备份和还原功能的应用程序的可访问存储位置
例如,假设使用Android Studio的Android设备监视器和一个名为todo.db的数据库包mjt.so46027137,则可以按如下方式提取数据库:-
在此屏幕截图中,添加了2个触发器,并选择删除第一个触发器:
然后可以将更改向后推,例如:-
运行以下命令:-
SQLiteDatabase db = databaseHelper.getWritableDatabase();
Cursor csr = db.rawQuery("SELECT * FROM sqlite_master",null);
while (csr.moveToNext()) {
Log.d("SQLITEMASTER","Row=" + csr.getPosition());
String sqlmstr = "";
for (int i=0; i < csr.getColumnCount(); i++) {
sqlmstr = sqlmstr + "\n\t" + "Column=" + csr.getColumnName(i) + " Data in Column=" + csr.getString(i);
}
Log.d("SQLITEMASTER", sqlmstr);
}
从而确认已添加触发器
上面的示例是使用Genymotion(模拟)设备完成的。如果您能够将数据库复制到SQLite管理工具(如SQLite Manager),我认为这需要根设备,或者,该应用程序内置了将数据库备份到可访问存储位置的方法,并且还具有从该存储位置的备份中恢复数据库的能力
然后,您可以在复制数据库后在SQLite管理工具中手动修改该数据库,例如,删除并创建触发器,然后将数据库复制回设备的原始位置(如果设备是根设备),或者复制回使用具有备份和还原功能的应用程序的可访问存储位置
例如,假设使用Android Studio的Android设备监视器和一个名为todo.db的数据库包mjt.so46027137,则可以按如下方式提取数据库:-
在此屏幕截图中,添加了2个触发器,并选择删除第一个触发器:
然后可以将更改向后推,例如:-
运行以下命令:-
SQLiteDatabase db = databaseHelper.getWritableDatabase();
Cursor csr = db.rawQuery("SELECT * FROM sqlite_master",null);
while (csr.moveToNext()) {
Log.d("SQLITEMASTER","Row=" + csr.getPosition());
String sqlmstr = "";
for (int i=0; i < csr.getColumnCount(); i++) {
sqlmstr = sqlmstr + "\n\t" + "Column=" + csr.getColumnName(i) + " Data in Column=" + csr.getString(i);
}
Log.d("SQLITEMASTER", sqlmstr);
}
从而确认已添加触发器
上面的示例是使用Genymotion(模拟)设备完成的。您是否排除通过SQL使用DROP TRIGGER?我如何执行“DROP TRIGGER”?我不能从触发器内部删除…正如我所说,我不能从java代码中执行sql命令。您是否排除通过sql使用DROP trigger?我如何执行“DROP trigger”?我不能从触发器内部删除…正如我所说,我不能从java代码中执行sql命令。你是说有人不能将sql命令存储到字符串中,然后相应地使用execSQL或rawquery?是的,SQLite本身没有execSQL
或rawquery
语句。我感到困惑。。你的意思是我不能进行如下链接所示的选择?“。无需在应用程序代码中处理此问题。”刚刚注意到这段宝贵的文字。谢谢你,伙计!你知道为什么触发器的条件(当)未确认时也会被评估吗?我的意思是,条件是假的,但我仍然得到一个错误,因为sqlite编译了一个“没有这样的表”错误。你是说有人不能将SQL命令存储到字符串中,然后相应地使用execSQL或rawquery?是的,sqlite本身没有execSQL
或rawquery
语句。我感到困惑。。你的意思是我不能进行如下链接所示的选择?“。无需在应用程序代码中处理此问题。”刚刚注意到这段宝贵的文字。谢谢你,伙计!你知道为什么触发器的条件(当)未确认时也会被评估吗?我的意思是,条件为false,但我仍然会得到一个错误,因为sqlite编译了一个“没有这样的表”错误