最近作了一個小網站,用到了一個使用sql server 2005的.net cms系統,可是如今我所買虛擬主機的服務商,不給虛擬主機提供sql server服務了,那就轉數據庫吧,轉啥好呢,思來想去,access?剛入行時候用了好久,簡單夠用,不過實在提不起興趣了,sqlite?嗯...還沒用過,只是簡單看過介紹,據說性能還不錯,那就試試吧,等等,不知道虛擬主機支持不支持?!百度!然而一大堆沒啥用處的提問和回答,也許可能大概是我搜索的關鍵詞不對,懶得管了,年齡大了,沒有那個勁兒了,實踐出真理,先上手試試驗證一下吧,說幹就幹html
先查查怎麼在本地建立和管理數據庫,而後選擇使用了SQLiteStudio這個軟件,而後新建個test數據庫->隨便插條數據->而後在vs建立個test web項目->數據庫文件扔進去->新建個頁面,查下數據顯示到頁面->本地運行,ok!,發佈,->上傳虛擬主機,懷着稍稍激動的心情,打開網址,ok!徹底能夠!mysql
這麼簡單嗎?nonono,運行以前仍是有點小小的障礙的:web
首先項目須要用到System.Data.SQLite.dll,到sqlite官網下一個吧,http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wikisql
而後添加引用,引用以後,還須要鏈接字符串,搜索(ss)! 嗯,和access很像,附個例子:數據庫
<add name="ConnectionString" connectionString="Data Source=|DataDirectory|testdb.db;Version=3;Pooling=true;FailIfMissing=false" providerName="System.Data.SQLite" />
這樣就能夠運行了!具體的參數還有很多,ss一下,根據需求本身設置。c#
而後開始改cms吧,首先是轉數據庫,一看錶,我尼瑪,好多表,本身一個一個建嗎?想一想都想打消折騰的念頭了,有沒有什麼工具能夠藉助呢?ss一下,還真有!ide
SQL server To SQLite DB Convert 這是一位叫liron.levi老外寫的,項目地址:https://www.codeproject.com/Articles/26932/Convert-SQL-Server-DB-to-SQLite-DB工具
簡直神器,界面以下性能
做者還給出了源代碼,在源代碼中能夠看到數據類型對應的轉換網站
/// <summary> /// Used when creating the CREATE TABLE DDL. Creates a single row /// for the specified column. /// </summary> /// <param name="col">The column schema</param> /// <returns>A single column line to be inserted into the general CREATE TABLE DDL statement</returns> private static string BuildColumnStatement(ColumnSchema col, TableSchema ts, ref bool pkey) { StringBuilder sb = new StringBuilder(); sb.Append("\t[" + col.ColumnName + "]\t"); // Special treatment for IDENTITY columns if (col.IsIdentity) { if (ts.PrimaryKey.Count == 1 && (col.ColumnType == "tinyint" || col.ColumnType == "int" || col.ColumnType == "smallint" || col.ColumnType == "bigint" || col.ColumnType == "integer")) { sb.Append("integer PRIMARY KEY AUTOINCREMENT"); pkey = true; } else sb.Append("integer"); } else { if (col.ColumnType == "int") sb.Append("integer"); else { sb.Append(col.ColumnType); } if (col.Length > 0) sb.Append("(" + col.Length + ")"); } if (!col.IsNullable) sb.Append(" NOT NULL"); if (col.IsCaseSensitivite.HasValue && !col.IsCaseSensitivite.Value) sb.Append(" COLLATE NOCASE"); string defval = StripParens(col.DefaultValue); defval = DiscardNational(defval); _log.Debug("DEFAULT VALUE BEFORE [" + col.DefaultValue + "] AFTER [" + defval + "]"); if (defval != string.Empty && defval.ToUpper().Contains("GETDATE")) { _log.Debug("converted SQL Server GETDATE() to CURRENT_TIMESTAMP for column [" + col.ColumnName + "]"); sb.Append(" DEFAULT (CURRENT_TIMESTAMP)"); } else if (defval != string.Empty && IsValidDefaultValue(defval)) sb.Append(" DEFAULT " + defval); return sb.ToString(); }
而後就用這個工具把cms的sql server數據庫轉換成sqlite數據庫文件,直接扔進cms項目中。
這樣就好了嗎?固然還有工做要作,原來項目中操做sql server的類庫也要換成sqlite的,sql語句也要作相應的轉換,下面就挑一些重點的說一說:
先說數據類型吧:
因爲在工具的源代碼中,主鍵無論什麼類型的int轉成sqlite都用的integer,有需求的能夠本身改代碼,不過最好要熟悉sqlite的數據類型。下面列出我在項目中所遇到的主要類型轉換
sql server | c# | sqlite | c# |
int | new SqlParameter("@id", SqlDbType.Int,4) | integer | new SQLiteParameter("@id", DbType.Int64,8) |
nvarchar | new SqlParameter("@id", SqlDbType.NVarChar,50) | nvarchar | new SQLiteParameter("@id", DbType.String,50) |
decimal | new SqlParameter("@id", SqlDbType.Decimal) | numeric | new SQLiteParameter("@id", DbType.Decimal) |
tinyint | new SqlParameter("@id", SqlDbType.TinyInt,1) | smallint | new SQLiteParameter("@id", DbType.Int16,1) |
ntext | new SqlParameter("@id", SqlDbType.NText) | text | new SQLiteParameter("@id", DbType.String) |
datetime | new SqlParameter("@id", SqlDbType.DateTime) | datetime | new SQLiteParameter("@id", DbType.DateTime) |
Image | new SqlParameter("@fs", SqlDbType.Image) | Binary | new SQLiteParameter("@fs", DbType.Binary) |
代碼數據類型轉換以後,就剩調試修改sql語句了,下面列出我在項目中遇到的比較主要的轉換
一、top語句,在sqlite中要使用limit,和mysql差很少,例如
sql:select top 10 * from table_1
sqlite:select * from table_1 limit 10
二、在插入一條數據後,要獲取最新的id
sql:select @@IDENTITY;
sqlite:select LAST_INSERT_ROWID();
三、計算時間差
sql:where datediff(d,field_time,getdate())>=0
sqlite:where JULIANDAY(datetime('now','localtime'))-JULIANDAY(field_time)>=0
四、分頁
sql:2005以上通常使用ROW_NUMBER()
select * from ( select row_number() over(order by id) as rows,* ) as t where rows between PageIndex*PageSize and PageIndex*PageSize+PageSize
sqlite:用 limit offset
select * from table_1 limit PageSize offset (PageIndex- 1) * PageSize
五、最讓人抓狂的是修改表部分的差別
這一部分單獨再寫一篇吧
時間不早了,來自老年人的嘆息.....