在下面的代码中,当我从单个表执行查询时,类型信息是完美的...但是,当我从两个相同定义的表的并集执行查询时...类型信息丢失(到a学位)如下:
Select * from Test1
Name (System.String)
Date (System.DateTime)
Value (System.Int32)
Select * from Test1 UNION Select * from Test2
Name (System.String)
Date (System.String) <== DateTime converted to String
Value (System.Int64) <== Int32 converted to Int64
当我使用UNION时,有没有办法保存类型信息?
代码:
sql = "Create Table Test1 " +
"([Name] string, [Date] date, [Value] int)";
using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{ command.ExecuteNonQuery(); }
sql = "Create Table Test2 " +
"([Name] string, [Date] date, [Value] int)";
using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{ command.ExecuteNonQuery(); }
sql = "Insert into Test1 (Name, Date, Value) values (@Name, @Date, @Value)";
using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{
command.Parameters.Add(new SQLiteParameter("@Name", "John Doe"));
command.Parameters.Add(new SQLiteParameter("@Date", DateTime.Parse("11/30/1958")));
command.Parameters.Add(new SQLiteParameter("@Value", 1));
command.ExecuteNonQuery();
}
sql = "Insert into Test2 (Name, Date, Value) values (@Name, @Date, @Value)";
using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{
command.Parameters.Add(new SQLiteParameter("@Name", "Brian Rice"));
command.Parameters.Add(new SQLiteParameter("@Date", DateTime.Parse("12/1/1970")));
command.Parameters.Add(new SQLiteParameter("@Value", 2));
command.ExecuteNonQuery();
}
sql = "Select * from Test1";
DataTable dt = new DataTable();
using (SQLiteCommand cmd = new SQLiteCommand(sql, connection))
{
// create data adapter
using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
{
// this will query your database and return the result to your datatable
da.Fill(dt);
}
}
Console.WriteLine(sql);
foreach (DataColumn column in dt.Columns)
Console.WriteLine(column.ColumnName + " (" + column.DataType + ")");
sql = "Select * from Test1 UNION Select * from Test2";
dt = new DataTable();
using (SQLiteCommand cmd = new SQLiteCommand(sql, connection))
{
// create data adapter
using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
{
// this will query your database and return the result to your datatable
da.Fill(dt);
}
}
Console.WriteLine(sql);
foreach (DataColumn column in dt.Columns)
Console.WriteLine(column.ColumnName + " (" + column.DataType + ")");
答案 0 :(得分:2)
我在这里修好了。
改为创建视图
CREATE VIEW "vwTest" AS Select * from Test1 UNION Select * from Test2
然后你应该从视图中选择
Select * from vwTest
答案 1 :(得分:1)
根据Datatypes In SQLite Version 3,在SQLite 3中没有真正的,或者我应该说,没有传统的数据类型。它明确表示既不是Date, Datetime也没有Bool存在。
而是有Storage Classes
:
还有类型亲和力的概念 它根据需要组织各种类和子类之间的转换。 (!?)
这可能是SQLite内部或.NET接口在处理UNION
语句的过程中产生您注意到的转换的原因。
这是文档中另一个有趣的引用:
SQLite没有为存储日期和/或时间而预留的存储类。相反,SQLite的内置日期和时间函数能够将日期和时间存储为TEXT,REAL或INTEGER值。
看起来,在解析UNION's SELECT
语句时,每个列都会转换为它后面可能找到的最通用的子类:对于所有INT,它将是INT64,这是显而易见的;对于日期而言,它是STRING,这不太明显但仍然合理......
由于你的桌子是相同的,你的价值也差不多似乎是一个人必须忍受的条款,我担心,除非不同的界面会采取不同的行为......