Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.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 如何处理基于更改的表名/列的sqlite触发器?_Android_Sqlite_Triggers_Android Sqlite - Fatal编程技术网

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编译了一个“没有这样的表”错误