欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5472|回復(fù): 0
收起左側(cè)

SQLITE的神奇問題,不管你信不信,反正我信了

[復(fù)制鏈接]
ID:127229 發(fā)表于 2016-6-19 18:03 | 顯示全部樓層 |閱讀模式
今天浪費(fèi)了幾個(gè)小時(shí)在解決SQLite 3這個(gè)破問題。

情況是這樣的,有一張SQLite表,里面定義了幾個(gè)浮點(diǎn)和整形數(shù)據(jù),里面有一些看起來一模一樣的數(shù)據(jù)行,
我用upate把某些字段相除,結(jié)果大跌眼鏡,除的結(jié)果不一樣,有幾行把小數(shù)點(diǎn)扔掉了,變成整形相除,有些行又對?
要不都對,要不都錯(cuò),同樣的一個(gè)update對同樣數(shù)據(jù)行操作竟然能出現(xiàn)不同結(jié)果?完全顛覆了俺對數(shù)據(jù)庫的理解,還好經(jīng)過在MSSQL上測試是對的,MyGod,上帝保佑微軟!

后經(jīng)過反復(fù)測試,找到的解決方案是:
建表時(shí),不能用NUMERIC(14,3),不能用DECIMAL(14,3),必須指定為REAL型。否則,有可能100.00插到數(shù)據(jù)庫成100整形了,即使你定義的字段為浮點(diǎn)型。似乎SQLite表每一行的每一個(gè)字段都可以有自已的類型,根據(jù)插入的數(shù)值自動(dòng)進(jìn)行判斷,太TMD神奇了,這是那個(gè)神人的大腦想出來的,俺的SQL思想差點(diǎn)整崩潰。

下次打死也不用超出SQLITE那5個(gè)基本類型的字段類型,SQLITE的神奇轉(zhuǎn)換功能可能會(huì)讓你死的莫名其妙啊。記之。



網(wǎng)上google到的一篇文章,參考一下:

SQLITE數(shù)據(jù)類型(轉(zhuǎn)貼)


SQLite與其他常見的DBMS的最大不同是它對數(shù)據(jù)類型的支持。其他常見的DBMS通常支持強(qiáng)類型的數(shù)據(jù),
也就是每一列的類型都必須預(yù)先指定,但是SQLite采用的是弱類型的字段。實(shí)際上,其內(nèi)部僅有下列五種存儲(chǔ)類型:


NULL: 表示一個(gè)NULL值


INTEGER: 用來存儲(chǔ)一個(gè)整數(shù),根據(jù)大小可以使用1,2,3,4,6,8位來存儲(chǔ).


REAL: IEEE 浮點(diǎn)數(shù)


TEXT: 按照字符串來存儲(chǔ)


BLOB: 按照二進(jìn)制值存儲(chǔ),不做任何改變.


要注意,這些類型是值本身的屬性,而不是列的屬性.


但是為了和其他DBMS(以及SQL標(biāo)準(zhǔn))兼容,在其create table語句中可以指定列的類型,為此,SQLite有個(gè)列相似性的概念(Column Affinity). 列相似性是列的屬性,SQLite有以下幾種列相似性:


TEXT: TEXT列使用NULL,TEXT或者BLOB存儲(chǔ)任何插入到此列的數(shù)據(jù),如果數(shù)據(jù)是數(shù)字,則轉(zhuǎn)換為TEXT.


NUMERIC: NUMERIC列可以使用任何存儲(chǔ)類型,它首先試圖將插入的數(shù)據(jù)轉(zhuǎn)換為REAL或INTEGER型的,如果成功則存儲(chǔ)為REAL和INTEGER型,否則不加改變的存入.


INTEGER:和NUMERIC類似,只是它將可以轉(zhuǎn)換為INTEGER值都轉(zhuǎn)換為INTEGER,如果是REAL型,且沒有小數(shù)部分,也轉(zhuǎn)為INTEGER


REAL: 和NUMERIC類型 只是它將可以轉(zhuǎn)換為REAL和INTEGER值都轉(zhuǎn)換為REAL.


NONE:不做任何改變的嘗試.


SQLite根據(jù)create table語句來決定每個(gè)列的列相似性.規(guī)則如下(大小寫均忽略):


1. 如果數(shù)據(jù)類型中包括INT,則是INTEGER


2. 如果數(shù)據(jù)類型中包括CHAR,CLOB,TEXT則是TEXT


3. 如果數(shù)據(jù)類型中包括BLOB,或者沒有指定數(shù)據(jù)類型,則是NONE


4. 如果數(shù)據(jù)類型中包括REAL,FLOA或者DOUB,則是REAL


5. 其余的情況都是NUMERIC


由上可知,對于sqlite來說 char,varchar,nchar,nvarchar等都是等價(jià)的,且后面最大長度也是沒有意義的。但是對于其他DBMS卻不是相同的。另外,列相似性僅僅是向Sqlite提出了一個(gè)存儲(chǔ)數(shù)據(jù)的建議,即使實(shí)際存儲(chǔ)的數(shù)據(jù)類型和列相似性不一致,SQLite還是可以成功插入的,下面給出一個(gè)例子來說明下以上論述,注意,這個(gè)例子需要在SQLite的命令行下運(yùn)行,如果在SQLite Expert工具下執(zhí)行,SQLite會(huì)進(jìn)行一些額外的處理。


如下圖,創(chuàng)建一個(gè)新表,兩列的類型分別是int 和varchar,但是還是可以插入其他類型的數(shù)據(jù),并且可以正確讀出。


要注意SQLite的這種特性可能會(huì)給SQLite的ADO驅(qū)動(dòng)造成一些麻煩,因?yàn)?NET都是強(qiáng)類型的語言,必須把數(shù)據(jù)庫中的字段轉(zhuǎn)換為合適的類型,所以在插入數(shù)據(jù)的時(shí)候,還是應(yīng)該嚴(yán)格的按照create table中的定義插入數(shù)據(jù)。


(2)自增列


在SQL Server中,只需要指定identity(1,1)就可以設(shè)定自增列,但是在SQLite中不支持這樣做。在SQLite中,任何一張表都有一個(gè)字段類型是Integer,且是自增的,這個(gè)列是作為B樹的索引的,它的名字是ROWID,如下圖所示:


test2表雖然只有一列,但是ROWID列還是存在的。在程序中對任何一張表都可以使用ROWID作為自增列。不過這樣可能導(dǎo)致和其他數(shù)據(jù)庫的不兼容,SQLite中如果一個(gè)列的聲明類型是Integer,并且是主鍵,那么這個(gè)列的名字就成為ROWID的別名。注意,聲明類型必須是 Integer,而不能是int或bigint之類。例如:


注意上面例子的最后3條語句,它顯示了SQLite默認(rèn)的自增列算法是在當(dāng)前表中最大的數(shù)再加1,這樣可能導(dǎo)致的結(jié)果是ID被重復(fù)使用——當(dāng)最后一條數(shù)據(jù)被刪除的時(shí)候。這與SQL Server的Identity列的行為是不一致的,例如:


SQL Server會(huì)記住每一次插入的序號,哪怕它已經(jīng)被刪除了。要實(shí)現(xiàn)SQL Server 這樣的效果,需要使用autoincrement關(guān)鍵字。如下例所示:


不過 autoincrement關(guān)鍵字不被SQL Server支持(我不知道SQL 92標(biāo)準(zhǔn)中是否有此關(guān)鍵字),同樣SQL Server的 indentity關(guān)鍵字在SQLite中也無法使用,因?yàn)镾QLite只要求聲明類型必須是integer才可以啟用自增列。所以,我想不出什么方法能使建庫的腳本能夠不加修改的被兩種數(shù)據(jù)庫使用。


(3) 日期函數(shù)


Sqlite的日期函數(shù)比較有特色,它的使用本質(zhì)上是調(diào)用C的庫函數(shù)strftime,基本使用方法如下:


(4) 不被支持的特性


用戶自定義函數(shù),存儲(chǔ)過程




回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表