如何从视图列获取SQLite列类型

时间:2019-02-01 13:22:36

标签: sql sqlite

在定义这样的视图时:

CREATE TABLE x (a VARCHAR(10));
CREATE VIEW v AS SELECT a, a || ' ' AS b FROM x;

我现在想使用以下方法发现视图列的列类型:

PRAGMA table_info('v');

不幸的是,这导致了

cid |name |type        |notnull |dflt_value |pk |
----|-----|------------|--------|-----------|---|
0   |a    |VARCHAR(10) |0       |           |0  |
1   |b    |            |0       |           |0  |

任何类型的列表达式都缺少列类型。是否有另一种方法来定义视图和/或查询表信息以获取列类型,或者这仅仅是SQLite的type affinity的工作方式?

2 个答案:

答案 0 :(得分:1)

我尝试过

CREATE VIEW v2 AS SELECT a, CAST((a || ' ') AS VARCHAR(11)) AS b FROM x;

也没有成功。

不是文档中记录的答案。你在这里参考 https://www.sqlite.org/datatype3.html吗?

  • 3.2表达式的亲和力:“ ...否则,表达式没有亲和力。
  • 3.3视图和子查询的列亲和力:...“表达式始终没有亲和力”。

实际上,您的问题可能是关于表/视图信息中的内容,而不是关于类型亲和力(也不是类型约束)。在我看来,这是SQLite3中的纯实现决定,除了设置CREATE VIEW中的预定义属性外,不设置视图信息。

答案 1 :(得分:0)

使用JDBC之类的客户端(例如通过Xerial)时,一种解决方法是从视图中获取一行并检查其中的ResultSetMetaData

try (Connection c = DriverManager.getConnection("jdbc:sqlite::memory:");
    Statement s = c.createStatement()) {

    s.execute("CREATE TABLE x (a VARCHAR(10));");
    s.execute("INSERT INTO x VALUES ('a')");
    s.execute("CREATE VIEW v AS SELECT a, a || ' ' AS b FROM x;");

    try (ResultSet rs = s.executeQuery("SELECT * FROM v LIMIT 1")) {
        ResultSetMetaData meta = rs.getMetaData();

        for (int i = 0; i < meta.getColumnCount(); i++) {
            String name = meta.getColumnName(i + 1);
            String type = meta.getColumnTypeName(i + 1);
            int precision = meta.getPrecision(i + 1);
            System.out.println(name + " " 
                             + type 
                             + (precision > 0 ? " (" + precision + ")" : ""));
        }
    }
}

这将产生:

a VARCHAR (10)
b TEXT

但是,当视图不产生任何行(如果列类型再次未知)时,这将不起作用:

a VARCHAR (10)
b NULL