【问题标题】:Getting the type of a column in SQLite在 SQLite 中获取列的类型
【发布时间】:2017-07-31 22:53:20
【问题描述】:

我的伙伴为我的 Android 应用创建了数据库。例如,其中一个表是这样创建的:

CREATE TABLE table1(
    id_fields_starring INTEGER PRIMARY KEY AUTOINCREMENT
    , fields_descriptor_id INTEGER NOT NULL
    , starring_id INTEGER NOT NULL
    , form_mandatory INTEGER NOT NULL DEFAULT 1
    , form_visible INTEGER NOT NULL DEFAULT 1
    , FOREIGN KEY(fields_descriptor_id) REFERENCES pr_fields_descriptor(id_fields_descriptor) ON DELETE CASCADE ON UPDATE CASCADE
    , FOREIGN KEY(starring_id) REFERENCES starring(id_starring) ON DELETE CASCADE ON UPDATE CASCADE
)

从表的字段中,我需要知道其中哪些是INTEGER NOT NULL,哪些是INTEGER NOT NULL DEFAULT 1,因为对于第一种情况,我必须动态创建一个EditText,而对于第二种情况,我必须创建一个@ 987654325@。有什么想法吗?

【问题讨论】:

  • 我认为目前是不可能的。我在我的应用程序中进行了硬编码。
  • @SheIs_LeThiCongNhan 看看 Jens 的回答。它有效。
  • 谢谢。但这不是官方方式,没有保证,我不会使用它。
  • 呃 ..PRAGMA table_info(..) 是在 SQLite 中查询表信息的首选方式 - 除非您感觉像 SQL-Rambo 并且想要筛选 SELECT * sqlite_master 的原始输出。

标签: android sqlite


【解决方案1】:

调用:

PRAGMA table_info(table1);

将转储表格信息,例如

cid|name                 |type    |notnull |dflt_value |pk
0  |id_fields_starring   |INTEGER |0       |           |1
1  |fields_descriptor_id |INTEGER |1       |           |0
2  |starring_id          |INTEGER |1       |           |0
3  |form_mandatory       |INTEGER |1       |1          |0
4  |form_visible         |INTEGER |1       |1          |0

只需在光标中找到带有notnull=1dflt_value=1 的行


编辑:

要列出定义为INTEGER NOT NULL DEFAULT 1 的所有列,这将起作用(helper 是您的SQLiteOpenHelper 实例):

SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery("PRAGMA table_info(table1)", null);
try {
    int nameIdx = cursor.getColumnIndexOrThrow("name");
    int typeIdx = cursor.getColumnIndexOrThrow("type");
    int notNullIdx = cursor.getColumnIndexOrThrow("notnull");
    int dfltValueIdx = cursor.getColumnIndexOrThrow("dflt_value");
    ArrayList<String> integerDefault1NotNull = new ArrayList<String>();
    while (cursor.moveToNext()) {
        String type = cursor.getString(typeIdx);
        if ("INTEGER".equals(type)) {
            // Integer column
            if (cursor.getInt(notNullIdx) == 1) {
                // NOT NULL
                String defaultValue = cursor.getString(dfltValueIdx);
                if ("1".equals(defaultValue)) {
                    integerDefault1NotNull.add(cursor.getString(nameIdx));
                }
            }
        }
    }
    System.out.println("integerDefault1NotNull now contains a list of all columns " +
            " defined as INTEGER NOT NULL DEFAULT 1, " + integerDefault1NotNull);
} finally {
    cursor.close();
}

【讨论】:

  • 詹斯,还有一个问题。我如何知道我没有 notnull=1 和 dflt_value=1 的每一列?我有一张有很多列的表,大约 48 列。
  • @Jens 此方法在模拟器上运行良好。今天我在设备上测试了我的应用程序,我发现它没有检测到任何非空且 dflt_value=1 的列,我有大约 18 个这样的列。我的设备有 2.1。这可能是问题吗?
  • table_info pragma 非常古老(自 2001 年以来一直存在) - 所以它并没有丢失。您的 2.1 设备是否已植根?
【解决方案2】:

对于那些希望在 Xamarin 中以编程方式执行此操作的人(如我),您可以对 SQLiteConnection 执行 PRAGMA 查询,如下所示:

connection.Query<SqliteColumninfo>($"PRAGMA table_info({tableName})");

我找不到在 PCL Sqlite 包中定义的用于收集结果的对象,因此我创建了一个类来收集上述组件:

public class SqliteColumninfo
{
   public string Cid { get; set; }
   public string Name { get; set; }
   public string Type { get; set; }
   public int NotNull { get; set; }
   public int Dflt_Value { get; set; }
   public int PK { get; set; }
}

【讨论】:

    猜你喜欢
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    相关资源
    最近更新 更多