SQLite是一款轻型的数据库,一个数据库就是一个文件,详细介绍参考官网:https://www.sqlite.org/index.html
SQLite 数据类型是一个用来指定任何对象的数据类型的属性。SQLite 中的每一列,每个变量和表达式都有相关的数据类型。
您可以在创建表的同时使用这些数据类型。SQLite 使用一个更普遍的动态类型系统。在 SQLite 中,值的数据类型与值本身是相关的,而不是与它的容器相关。
SQLite数据与vb.net教程常见的MySQL、SQL等的数据库不一样,它是动态类c#教程型数据库,每个值在数据python基础教程库占的存储空间根java基础教程据值的大小确sql教程定,使用时需要注意数据类型的问题。
每个存储在 SQLite 数据库中的值都具有以下存储类之一:
存储类 | 描述 |
---|---|
NULL | 值是一个 NULL 值。 |
INTEGER | 值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。 |
REAL | 值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。 |
TEXT | 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。 |
BLOB | 值是一个 blob 数据,完全根据它的输入存储。 |
SQLite支持列的亲和类型概念,任何列仍然可以存储任何类型的数据,当数据插入时该字段的数据将会优先采用亲和类型作为该值的存储方式。
创建 SQLite3 表时可使用的各种数据类型名称及相应的亲和类型,如下:
数据类型 | 亲和类型 |
---|---|
INT INTEGER TINYINT SMALLINT MEDIUMINT BIGINT UNSIGNED BIG INT INT2 INT8 |
INTEGER:对于亲缘类型为INTEGER的字段,其规则等同于NUMERIC,唯一差别是在执行CAST表达式时。 |
CHARACTER(20) VARCHAR(255) VARYING CHARACTER(255) NCHAR(55) NATIVE CHARACTER(70) NVARCHAR(100) TEXT CLOB |
TEXT:数值型数据在被插入之前,需要先被转换为文本格式,之后再插入到目标字段中。 |
BLOB no datatype specified |
NONE:不做任何的转换,直接以该数据所属的数据类型进行存储。 |
REAL DOUBLE DOUBLE PRECISION FLOAT |
REAL:其规则基本等同于NUMERIC,唯一的差别是不会将"30000.0"这样的文本数据转换为INTEGER存储方式。 |
NUMERIC DECIMAL(10,5) BOOLEAN DATE DATETIME |
NUMERIC 当文本数据被插入到亲缘性为NUMERIC的字段中时: 如果转换操作不会导致数据信息丢失以及完全可逆,那么SQLite就会将该文本数据转换为INTEGER或REAL类型的数据; 如果转换失败,SQLite仍会以TEXT方式存储该数据。 对于NULL或BLOB类型的新数据,SQLite将不做任何转换,直接以NULL或BLOB的方式存储该数据。 注:对于浮点格式的常量文本,如"30000.0",如果该值可以转换为INTEGER同时又不会丢失数值信息,那么SQLite就会将其转换为INTEGER的存储方式。 |
在C#中使用SQLite数据库需要引用System.Data.SQLite.dll,下载链接:http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
注:System.Data.SQLite是SQLite的ADO.NET提供程序,两者是两个不同的开源项目,现在System.Data.SQLite的开发和维护工作大部分由SQLite开发团队执行。
System.Data.SQLite的下载页面选项太多,一般人进来都不清楚要下载那些内容,下面对下载界面中的软件包做一个简单介绍。
下载内容按类型分为安装包、非静态连接的二进制包和静态连接的二进制包三种,区别如下:
注:如果所有目标机器已经安装了VisualC++运行时,或者可以容易地部署,则应该避免“静态”包。
每个类型都按.NET版本分成了若干小组,每个.NET版本又分为32位和64位两组:
注:虽然.NET高版本兼容低版本,但强烈建议选择与目标.NET Framework版本匹配的包。
在每个.NET版本-位数分组中都有2个文件包,一个带有“bundle”字样,另一个没有:
注:除非认为绝对必要,否则应避免使用“bundle”包。
根据上面的介绍,如果开发机器和客户机器可能具有不同的处理器体系结构,则可能需要一个以上的二进制程序包。
本机库预加载功能从1.0.80.0版本开始可用,并且默认情况下已启用,能够自动适应当前系统的位数。为了利用此功能,必须将单独的托管程序集和互操作程序集与XCOPY部署一起使用(混合模式程序集、安装软件包部署不支持此功能)。
使用本机库预加载功能时,应用程序部署看起来如下( bin 表示将在目标计算机上部署应用程序二进制文件的目录):
启用本机库预加载功能并显示上面的应用程序部署后,System.Data.SQLite仅限托管程序集将尝试自动检测当前进程的处理器体系结构并预加载适当的本机库,此时不用考虑客户机器的是64位还是32位。
我把.NET的4.0 、4.5版本对应的软件包按本机库预加载功能的要求重新组装,使用时直接复制到Debug目录下即可:
注:官方建议不使用静态的二进制包,我个人则喜欢用静态的二进制包,这样就不用考虑客户机器上是否安装有对应的VC运行时库了。
工具类大部分内容来自c# Sqlite帮助类,考虑到SQLite是一个数据库一个文件、一个项目可能需要多个数据库,我将工具类改为通过对象实例操作数据库并提供一个静态的对象实例字典。
工具类代码如下:
public class SQLiteHelper
{
///
/// 数据库列表
///
public static Dictionary DataBaceList = new Dictionary();
///
/// 构造函数
///
/// 数据库文件名
public SQLiteHelper(string filename=null)
{
DataSource = filename;
}
///
/// 数据库地址
///
public string DataSource { get; set; }
///
/// 创建数据库,如果数据库文件存在则忽略此操作
///
public void CreateDataBase()
{
string path = Path.GetDirectoryName(DataSource);
if ((!string.IsNullOrWhiteSpace(path)) && (!Directory.Exists(path))) Directory.CreateDirectory(path);
if (!File.Exists(DataSource)) SQLiteConnection.CreateFile(DataSource);
}
///
/// 获得连接对象
///
/// SQLiteConnection
public SQLiteConnection GetSQLiteConnection()
{
string connStr =string.Format("Data Source={0}", DataSource);
var con = new SQLiteConnection(connStr);
return con;
}
///
/// 准备操作命令参数
///
/// SQLiteCommand
/// SQLiteConnection
/// Sql命令文本
/// 参数数组
private static void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, Dictionary data)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Parameters.Clear();
cmd.Connection = conn;
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 30;
if (data != null && data.Count >= 1)
{
foreach (KeyValuePair val in data)
{
cmd.Parameters.AddWithValue(val.Key, val.Value);
}
}
}
///
/// 查询,返回DataSet
///
/// Sql命令文本
/// 参数数组
/// DataSet
public DataSet ExecuteDataset(string cmdText, Dictionary data = null)
{
var ds = new DataSet();
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
var da = new SQLiteDataAdapter(command);
da.Fill(ds);
}
return ds;
}
///
/// 查询,返回DataTable
///
/// Sql命令文本
/// 参数数组
/// DataTable
public DataTable ExecuteDataTable(string cmdText, Dictionary data = null)
{
var dt = new DataTable();
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
SQLiteDataReader reader = command.ExecuteReader();
dt.Load(reader);
}
return dt;
}
///
/// 返回一行数据
///
/// Sql命令文本
/// 参数数组
/// DataRow
public DataRow ExecuteDataRow(string cmdText, Dictionary data = null)
{
DataSet ds = ExecuteDataset(cmdText, data);
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
return ds.Tables[0].Rows[0];
return null;
}
///
/// 执行数据库操作
///
/// Sql命令文本
/// 传入的参数
/// 返回受影响的行数
public int ExecuteNonQuery(string cmdText, Dictionary data=null)
{
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
return command.ExecuteNonQuery();
}
}
///
/// 返回SqlDataReader对象
///
/// Sql命令文本
/// 传入的参数
/// SQLiteDataReader
public SQLiteDataReader ExecuteReader(string cmdText, Dictionary data = null)
{
var command = new SQLiteCommand();
SQLiteConnection connection = GetSQLiteConnection();
try
{
PrepareCommand(command, connection, cmdText, data);
SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
catch
{
connection.Close();
command.Dispose();
throw;
}
}
///
/// 返回结果集中的第一行第一列,忽略其他行或列
///
/// Sql命令文本
/// 传入的参数
/// object
public object ExecuteScalar(string cmdText, Dictionary data = null)
{
using (SQLiteConnection connection = GetSQLiteConnection())
{
var cmd = new SQLiteCommand();
PrepareCommand(cmd, connection, cmdText, data);
return cmd.ExecuteScalar();
}
}
///
/// 分页查询
///
/// 总记录数
/// 页牵引
/// 页大小
/// Sql命令文本
/// 查询总记录数的Sql文本
/// 命令参数
/// DataSet
public DataSet ExecutePager(ref int recordCount, int pageIndex, int pageSize, string cmdText, string countText, Dictionary data = null)
{
if (recordCount < 0)
recordCount = int.Parse(ExecuteScalar(countText, data).ToString());
var ds = new DataSet();
using (SQLiteConnection connection = GetSQLiteConnection())
{
var command = new SQLiteCommand();
PrepareCommand(command, connection, cmdText, data);
var da = new SQLiteDataAdapter(command);
da.Fill(ds, (pageIndex - 1) * pageSize, pageSize, "result");
}
return ds;
}
///
/// 重新组织数据库:VACUUM 将会从头重新组织数据库
///
public void ResetDataBass()
{
using (SQLiteConnection conn = GetSQLiteConnection())
{
var cmd = new SQLiteCommand();
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Parameters.Clear();
cmd.Connection = conn;
cmd.CommandText = "vacuum";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 30;
cmd.ExecuteNonQuery();
}
}
}
工具类使用方法如下:
static void Main(string[] args)
{
SQLiteHelper testDb = new SQLiteHelper("test.db");
SQLiteHelper.DataBaceList.Add("TEST", testDb);
//建库
testDb.CreateDataBase();
//建表
StringBuilder sbr = new StringBuilder();
sbr.AppendLine("CREATE TABLE IF NOT EXISTS `test_table`(");
sbr.AppendLine("`id` INTEGER PRIMARY KEY AUTOINCREMENT,");//自增id主键
sbr.AppendLine("`name` VARCHAR(100) NOT NULL,");
sbr.AppendLine("`password` VARCHAR(40) NOT NULL,");
sbr.AppendLine("`create_time` datetime DEFAULT CURRENT_TIMESTAMP,");
sbr.AppendLine("`update_time` datetime DEFAULT CURRENT_TIMESTAMP );");
sbr.AppendLine();
sbr.AppendLine("CREATE TRIGGER IF NOT EXISTS `trigger_test_table_update_time` ");//触发器-自动更新update_time
sbr.AppendLine("AFTER UPDATE ON `test_table` ");
sbr.AppendLine("FOR EACH ROW ");
sbr.AppendLine("BEGIN ");
sbr.AppendLine("UPDATE `test_table` SET `update_time` = CURRENT_TIMESTAMP WHERE id = old.id; ");
sbr.AppendLine("END;");
string cmdText = sbr.ToString();
int val = testDb.ExecuteNonQuery(cmdText);
Console.WriteLine("影响行数:" + val);
//增
sbr.Clear();
sbr.Append("INSERT INTO test_table (name,password) VALUES ");
sbr.Append("(11,111), ");
sbr.Append("(12,222); ");
cmdText = sbr.ToString();
val = testDb.ExecuteNonQuery(cmdText);
Console.WriteLine("影响行数:" + val);
//删
sbr.Clear();
sbr.Append("DELETE FROM test_table ");
sbr.Append("WHERE id=1;");
cmdText = sbr.ToString();
val = testDb.ExecuteNonQuery(cmdText);
Console.WriteLine("影响行数:" + val);
//改
sbr.Clear();
sbr.Append("UPDATE test_table SET ");
sbr.Append("name='13', ");
sbr.Append("password='333' ");
sbr.Append("WHERE id=@id;");
cmdText = sbr.ToString();
Dictionary data = new Dictionary();
data.Add("@id", "2");
val = testDb.ExecuteNonQuery(cmdText, data);
Console.WriteLine("影响行数:" + val);
//查
sbr.Clear();
sbr.Append("SELECT name,password FROM test_table ");
sbr.Append("WHERE id=@id;");
cmdText = sbr.ToString();
DataTable dt = testDb.ExecuteDataTable(cmdText, data);
Console.WriteLine("结果行数:" + dt.Rows.Count);
//删除表
sbr.Clear();
sbr.Append("DROP TABLE test_table;");
cmdText = sbr.ToString();
val = SQLiteHelper.DataBaceList["TEST"].ExecuteNonQuery(cmdText);
Console.WriteLine("影响行数:" + val);
//重组数据库
SQLiteHelper.DataBaceList["TEST"].ResetDataBass();
Console.ReadKey();
}