標題: SQLITE的神奇問題,不管你信不信,反正我信了 [打印本頁]
作者: 51hei不 時間: 2016-6-19 18:03
標題: SQLITE的神奇問題,不管你信不信,反正我信了
今天浪費了幾個小時在解決SQLite 3這個破問題。
情況是這樣的,有一張SQLite表,里面定義了幾個浮點和整形數據,里面有一些看起來一模一樣的數據行,
我用upate把某些字段相除,結果大跌眼鏡,除的結果不一樣,有幾行把小數點扔掉了,變成整形相除,有些行又對?
要不都對,要不都錯,同樣的一個update對同樣數據行操作竟然能出現不同結果?完全顛覆了俺對數據庫的理解,還好經過在MSSQL上測試是對的,MyGod,上帝保佑微軟!
后經過反復測試,找到的解決方案是:
建表時,不能用NUMERIC(14,3),不能用DECIMAL(14,3),必須指定為REAL型。否則,有可能100.00插到數據庫成100整形了,即使你定義的字段為浮點型。似乎SQLite表每一行的每一個字段都可以有自已的類型,根據插入的數值自動進行判斷,太TMD神奇了,這是那個神人的大腦想出來的,俺的SQL思想差點整崩潰。
下次打死也不用超出SQLITE那5個基本類型的字段類型,SQLITE的神奇轉換功能可能會讓你死的莫名其妙啊。記之。
網上google到的一篇文章,參考一下:
SQLITE數據類型(轉貼)
SQLite與其他常見的DBMS的最大不同是它對數據類型的支持。其他常見的DBMS通常支持強類型的數據,
也就是每一列的類型都必須預先指定,但是SQLite采用的是弱類型的字段。實際上,其內部僅有下列五種存儲類型:
NULL: 表示一個NULL值
INTEGER: 用來存儲一個整數,根據大小可以使用1,2,3,4,6,8位來存儲.
REAL: IEEE 浮點數
TEXT: 按照字符串來存儲
BLOB: 按照二進制值存儲,不做任何改變.
要注意,這些類型是值本身的屬性,而不是列的屬性.
但是為了和其他DBMS(以及SQL標準)兼容,在其create table語句中可以指定列的類型,為此,SQLite有個列相似性的概念(Column Affinity). 列相似性是列的屬性,SQLite有以下幾種列相似性:
TEXT: TEXT列使用NULL,TEXT或者BLOB存儲任何插入到此列的數據,如果數據是數字,則轉換為TEXT.
NUMERIC: NUMERIC列可以使用任何存儲類型,它首先試圖將插入的數據轉換為REAL或INTEGER型的,如果成功則存儲為REAL和INTEGER型,否則不加改變的存入.
INTEGER:和NUMERIC類似,只是它將可以轉換為INTEGER值都轉換為INTEGER,如果是REAL型,且沒有小數部分,也轉為INTEGER
REAL: 和NUMERIC類型 只是它將可以轉換為REAL和INTEGER值都轉換為REAL.
NONE:不做任何改變的嘗試.
SQLite根據create table語句來決定每個列的列相似性.規則如下(大小寫均忽略):
1. 如果數據類型中包括INT,則是INTEGER
2. 如果數據類型中包括CHAR,CLOB,TEXT則是TEXT
3. 如果數據類型中包括BLOB,或者沒有指定數據類型,則是NONE
4. 如果數據類型中包括REAL,FLOA或者DOUB,則是REAL
5. 其余的情況都是NUMERIC
由上可知,對于sqlite來說 char,varchar,nchar,nvarchar等都是等價的,且后面最大長度也是沒有意義的。但是對于其他DBMS卻不是相同的。另外,列相似性僅僅是向Sqlite提出了一個存儲數據的建議,即使實際存儲的數據類型和列相似性不一致,SQLite還是可以成功插入的,下面給出一個例子來說明下以上論述,注意,這個例子需要在SQLite的命令行下運行,如果在SQLite Expert工具下執行,SQLite會進行一些額外的處理。
如下圖,創建一個新表,兩列的類型分別是int 和varchar,但是還是可以插入其他類型的數據,并且可以正確讀出。
要注意SQLite的這種特性可能會給SQLite的ADO驅動造成一些麻煩,因為.NET都是強類型的語言,必須把數據庫中的字段轉換為合適的類型,所以在插入數據的時候,還是應該嚴格的按照create table中的定義插入數據。
(2)自增列
在SQL Server中,只需要指定identity(1,1)就可以設定自增列,但是在SQLite中不支持這樣做。在SQLite中,任何一張表都有一個字段類型是Integer,且是自增的,這個列是作為B樹的索引的,它的名字是ROWID,如下圖所示:
test2表雖然只有一列,但是ROWID列還是存在的。在程序中對任何一張表都可以使用ROWID作為自增列。不過這樣可能導致和其他數據庫的不兼容,SQLite中如果一個列的聲明類型是Integer,并且是主鍵,那么這個列的名字就成為ROWID的別名。注意,聲明類型必須是 Integer,而不能是int或bigint之類。例如:
注意上面例子的最后3條語句,它顯示了SQLite默認的自增列算法是在當前表中最大的數再加1,這樣可能導致的結果是ID被重復使用——當最后一條數據被刪除的時候。這與SQL Server的Identity列的行為是不一致的,例如:
SQL Server會記住每一次插入的序號,哪怕它已經被刪除了。要實現SQL Server 這樣的效果,需要使用autoincrement關鍵字。如下例所示:
不過 autoincrement關鍵字不被SQL Server支持(我不知道SQL 92標準中是否有此關鍵字),同樣SQL Server的 indentity關鍵字在SQLite中也無法使用,因為SQLite只要求聲明類型必須是integer才可以啟用自增列。所以,我想不出什么方法能使建庫的腳本能夠不加修改的被兩種數據庫使用。
(3) 日期函數
Sqlite的日期函數比較有特色,它的使用本質上是調用C的庫函數strftime,基本使用方法如下:
(4) 不被支持的特性
用戶自定義函數,存儲過程
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
欧美日日日日bbbbb视频
|
伊人在线
|
91精品国产91久久综合桃花
|
天天曰夜夜操
|
亚洲成人一级
|
中国大陆高清aⅴ毛片
|
色爱综合
|
亚洲综合大片69999
|
m豆传媒在线链接观看
|
一区二区三区国产精品
|
成人一区二区三区在线观看
|
亚洲精彩视频在线观看
|
亚洲精品区
|
黑人精品欧美一区二区蜜桃
|
97人人爱
|
午夜激情一区
|
亚洲免费视频在线观看
|
天天操天天摸天天爽
|
欧美日韩国产在线观看
|
日本不卡免费新一二三区
|
亚洲视频中文字幕
|
99久久久久久久
|
在线国产一区二区
|
av免费网址|
久久久久亚洲精品
|
国产又爽又黄的视频
|
久久一二区
|
精品美女久久久
|
伊人伊人
|
亚洲毛片在线观看
|
久久剧场
|
激情在线视频
|
超级碰在线
|
免费h在线
|
久久综合一区二区三区
|
国产精品免费观看
|
日韩美女在线看免费观看
|
国产精品1区2区
|
亚洲一区二区三区视频在线
|
久久久久久久国产
|
国产精品精品视频一区二区三区
|