【问题标题】:Sqlite metadata query fails with Microsoft.Data.Sqlite, works with System.Data.SQLiteSqlite 元数据查询因 Microsoft.Data.Sqlite 失败,可与 System.Data.SQLite 一起使用
【发布时间】:2020-06-07 05:29:32
【问题描述】:

我有一个直接取自 Microsoft 文档(请参阅 https://docs.microsoft.com/en-us/dotnet/standard/data/sqlite/metadata)的简单查询,该查询失败。根据文档,针对sqlite_master 的查询应该可以按预期工作,但它们会引发异常,即使在我创建数据库并创建表之后也是如此。

SELECT t.name AS tbl_name, c.name, c.type, c.[notnull], c.dflt_value, c.pk FROM sqlite_master AS t, pragma_table_info(t.name) AS c WHERE t.type = 'table';

这是突出问题的孤立代码:

using System;
using System.Data;
using Microsoft.Data.Sqlite;

namespace Test.Library
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                string connStr = "Data Source=test.db";

                string tableQuery = "CREATE TABLE IF NOT EXISTS 'company' (id Integer PRIMARY KEY AUTOINCREMENT NOT NULL , name Text COLLATE NOCASE , postal Integer);";
                string metadataQuery = "SELECT t.name AS tbl_name, c.name, c.type, c.[notnull], c.dflt_value, c.pk FROM sqlite_master AS t, pragma_table_info(t.name) AS c WHERE t.type = 'table';";

                using (SqliteConnection conn = new SqliteConnection(connStr))
                {
                    conn.Open();
                    DataTable result = Query(tableQuery, conn);
                    Console.WriteLine(result.Rows.Count);

                    result = Query(metadataQuery, conn);
                    Console.WriteLine(result.Rows.Count);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.ReadLine();
        }

        private static DataTable Query(string query, SqliteConnection conn)
        {
            using (SqliteCommand cmd = new SqliteCommand(query, conn))
            {
                using (SqliteDataReader rdr = cmd.ExecuteReader())
                {
                    DataTable result = new DataTable();
                    result.Load(rdr);
                    return result;
                }
            }
        }
    }
}

并且控制台输出包括异常(注意第一行是执行第一个查询返回的行数的Console.WriteLine,即0)...

0
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table column: pragma_table_info.name'.
   at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
   at Microsoft.Data.Sqlite.SqliteDataReader.GetSchemaTable()
   at System.Data.ProviderBase.SchemaMapping..ctor(DataAdapter adapter, DataSet dataset, DataTable datatable, DataReaderContainer dataReader, Boolean keyInfo, SchemaType schemaType, String sourceTableName, Boolean gettingData, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.FillMappingInternal(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.FillMapping(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 schemaCount, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
   at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
   at System.Data.DataTable.Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler)
   at System.Data.DataTable.Load(IDataReader reader)
   at Test.Library.Program.Query(String query, SqliteConnection conn) in C:\Code\Misc\Program.cs:line 43
   at Test.Library.Program.Main(String[] args) in C:\Code\Misc\Program.cs:line 24

请注意,metadataQuery 直接来自微软的网站(上面的链接)。

当我使用 DB Browser for Sqlite(或类似的)执行相同的查询时,它工作正常,并且,当使用 System.Data.SQLite 的相同代码时,它工作正常(显然类名的大小写略有不同,等等)。

谢谢!

【问题讨论】:

  • 您使用的是哪个(确切)版本的 SQLite?
  • 我假设任何 Microsoft.Data.Sqlite 使用。但我已经安装了:sqlite3 --version 返回3.29.0 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
  • 您没有将连接传递给 Query 方法,并且字符串 metadataQuery 不以分号结尾。不确定此代码是否构建?
  • 这是伪代码。实际的代码确实传递了这个。它与 System.Data.Sqlite 配合得很好。
  • 回到电脑后会用实际更新伪代码。

标签: c# sqlite microsoft.data.sqlite


【解决方案1】:

Microsoft.Data.Sqlite 如何处理从 pragma_table_info 等表值函数查询数据 directly 似乎存在问题。

另一方面,为了准确获取所有表的所有元数据信息,下面的查询有效(用nuget version 3.1.4测试)

string metadataQuery = "DROP TABLE IF EXISTS info;" +
                       "CREATE TEMPORARY TABLE info AS SELECT t.name AS tbl_name, c.name, c.type, c.[notnull], c.dflt_value, c.pk FROM sqlite_master AS t, pragma_table_info(t.name) AS c WHERE t.type = 'table';" +
                       "SELECT * FROM  info";

有关类似问题,请参阅here

此外 Microsoft.Data.Sqlite 在获取架构信息方面有limitations

【讨论】:

  • 谢谢,您的解决方法正是我所希望的。
  • 我很高兴它有帮助:)
猜你喜欢
  • 2019-01-26
  • 2021-05-01
  • 1970-01-01
  • 2019-01-04
  • 2021-10-20
  • 1970-01-01
  • 2013-03-20
  • 2021-09-23
相关资源
最近更新 更多