android 數據庫 sqlite數據類型(時間 日期 double等)


sqlite3支持的數據類型:

NULL、INTEGER、REAL、TEXT、BLOB
但是,sqlite3也支持如下的數據類型
smallint           16位整數
integer             32位整數
decimal(p,s)   p是精確值,s是小數位數
float                  32位實數
double             64位實數
char(n)             n長度字符串,不能超過254
varchar(n)        長度不固定最大字符串長度為n,n不超過4000
graphic(n)        和 char(n) 一樣,但是單位是兩個字符double-bytes,n不超過127(中文字)
vargraphic(n)  可變長度且最大長度為n

date                  包含了年份、月份、日期
time                  包含了小時、分鍾、秒
timestamp       包含了年、月、日、時、分、秒、千分之一秒

sqlite3支持的函數

【1】日期函數

datetime() : 產生日期和時間
date(): 產生日期
time():產生時間
strftime():對以上3個函數產生的日期和時間進行格式化

用法實例:
1、SELECT date('2011-9-9','+1 day','+1 year'); 結果是 2010-09-10
2、SELECT datetime('now'); 當前日期和時間
3、SELECT datetime('now', 'start of month'); 本月的第一天零點,也可以設置年和日的第一天
4、SELECT datetime('now','+1 hour','-12 minute'); 當前時間加48分鍾

strftime()函數可以將YYYY-MM-DD HH:MM:SS格式的日期字符串轉換為其它形式的字符串

%d:天數,01-31
%f :小數形式的秒,SS.SSS
%H:小時
%j  :某一天是該年的第幾天,001-366
%m:月份,00-12
%M:分鍾,00-59
%s:從1970到現在的秒數
%S:秒,00-59
%w:星期,0-6,0是星期天
%W:某天是該年的第幾周,01-53
%Y:年,YYYY
%% 百分號

應用舉例:
SELECT strftime('%Y.%m.%d %H:%M:%S','now','localtime');


二、【算術函數】

abs(X):返回絕對值
max(X,Y[,...]):返回最大值
min(X,Y,[,...]):返回最小值
random(*):返回隨機數
round(X[,Y]): 四舍五入

三、【字符串處理函數】

length(x) :返回字符串字符個數
lower(x) :大寫轉小寫
upper(x):小寫轉大寫
substr(x,y,Z):截取子串
like(A,B):確定給定的字符串與指定的模式是否匹配

四、【條件判斷函數、集合函數、其它函數】

typeof(x):返回數據的類型
last_insert_rowid():返回最后插入的數據的ID

********************************************************************************************************************

sqlite3提供了C函數接口來操作sqlite3數據庫,其中有個關鍵數據結構 sqlite3 * 類型

1、打開數據庫
int sqlite3_open(文件名,sqlite3 **);  - 文件名若不存在,則會自動創建
返回SQLITE_OK表示操作正常,這些宏的定義在sqlite3.h文件中定義,看源代碼會懂的更多

2、關閉數據庫
int sqlite3_close(sqlite3 *);

3、SQL語句操作
int sqlite3_exec(sqlite3 *,const char *sql, sqlite3_callback,void *,char **errmsg);
這就是執行一條sql語句的函數
參數1:open函數得到的指針
參數2:一條sql語句,以'\0'結尾
參數3:sqlite3_callback是回調,當這條語句執行后,sqlite3會調用你提供的這個函數,回調函數要查閱資料
參數4:void *是自己提供的指針,可以傳遞任何指針到這里,這個參數最終會傳到回調函數里面,如果不需要
傳到回調函數里面,則可以設置為NULL
參數5:錯誤信息,當執行失敗時,可以查閱這個指針,可以利用printf("%s\n",errmsg)得到一串字符串信息,
該信息表明出錯的地方

通常,sqlite3_callback和void *都設置為NULL,表示不需要回調,比如做insert、delete操作,就沒有必要使用回調,而當使用select時,就要使用回調,因為sqlite3把數據查出來,得通過回調來說明查出什么數據


回調函數的定義格式:
typedef int (*sqlite3_callback)(void *,int,char **,char **);

實例如下:

[cpp]  view plain copy
  1. //sqlite 每查到一條記錄,就調用一次這個回調  
  2. int LoadMyInfo(void *para,int n_column,char **column_value,char **column_name)  
  3. {  
  4.     /*para: 在sqlite3里傳入的void *參數,通過該參數可以傳入一些特殊指針 
  5.      *如類指針、結構指針,然后在這里轉換成對應的類型(這里是void *類型), 
  6.      *必須強制轉換成自己的類型才可用,然后操作這些數據*/  
  7.        
  8.     //n_column: 該記錄有多少個字段(列)  
  9.       
  10.     /*char **column_value 保存着查出來的數據,實際上是個1維數組,每一個元素都是 
  11.      *char *值,是一個字段內容(用字符串表示,以\0結尾)*/  
  12.        
  13.     //char **column_name 與 column_value 是對應的,表示這個字段的字段名稱  
  14.       
  15.     //這里不是用para參數  
  16.       
  17.     printf("%=記錄包含%d\n個字段",n_column);  
  18.       
  19.     for(i=0;i<n_column;i++)  
  20.     {  
  21.         printf("字段名: %s ,字段值:%s\n",column_name[i],column_value[i]);  
  22.     }  
  23.       
  24.     printf("\n");  
  25.       
  26.     return 0;  
  27. }  
  28.   
  29. int main(int , char **)  
  30. {  
  31.     sqlite3 *db;  
  32.     int result;  
  33.     char *errmsg = NULL;  
  34.     char sql[512];  
  35.       
  36.     result = sqlite3_open("My.db",&db);  
  37.     if(result != SQLITE_OK)  
  38.     {  
  39.         //數據庫打開失敗  
  40.         return -1;   
  41.     }  
  42.       
  43.     //創建數據表  
  44.     strcpy(sql,"CREATE TABLE test(ID INTEGER PRIMARY KEY,NAME VARCHAR(32));");  
  45.     result = sqlite3_exec(db,sql,NULL,NULL,errmsg);  
  46.     if(result != SQLITE_OK)  
  47.     {  
  48.         printf("創建表失敗,錯誤:%s\n",errmsg);  
  49.     }  
  50.       
  51.     //插入記錄  
  52.     strcpy(sql,"INSERT INTO test VALUES(1,'OK');");  
  53.     result = sqlite3_exec(db,sql,0,0,errmsg);  
  54.     if(result != SQLITE_OK)  
  55.     {  
  56.         printf("插入記錄失敗,錯誤:%s\n",errmsg);  
  57.     }  
  58.       
  59.     //查詢數據庫  
  60.     strcpy(sql,"SELECT * FROM test;");  
  61.     result = sqlite3_exec(db,sql,LoadMyInfo,NULL,errmsg);  
  62.       
  63.     sqlite3_close(db);  
  64.       
  65.     return 0;  
  66. }  


以上是通過回調查詢數據庫,如果該函數在C++中,就要將其聲明成static類型,因為C++
成員函數隱藏了一個參數:this,C++調用類的成員函數的時候,隱含把類指針當函數的第
一個參數傳遞進去,就與上面的sqlite回調函數參數不符

除了使用回調來查詢,還可以使用非回調的查詢,通過sqlite3_get_table函數做到
int sqlite3_get_table(sqlite3*,const char *sql,char ***resultp,int *nrow,int *ncolumn,char **errmsg);
參數3:resultp 是一維數組,第一行是字段名稱,跟着是每個字段的值
參數4:查詢共多少條記錄
參數5:查詢共多少個字段

操作實例如下:

[cpp]  view plain copy
  1. int main(int ,char **)  
  2. {  
  3.     sqlite3 *db;  
  4.     int result;  
  5.     char *errmsg = NULL;  
  6.       
  7.     char **dbResult;  
  8.     int nRow,nColumn;  
  9.     int i,j;  
  10.     int index;  
  11.       
  12.     char sql[512];  
  13.       
  14.     result = sqlite3_open("My.db",&db);  
  15.     if(result != SQLITE_OK)  
  16.     {  
  17.         return -1;  
  18.     }  
  19.       
  20.     result = sqlite3_get_table(db,sql,&dbResult,&nRow,&nColumn,&errmsg);  
  21.     //查詢成功  
  22.     if(SQLITE_OK == result)   
  23.     {  
  24.         //dbResult第一行是字段名稱,從nColumn索引開始時真正的數據  
  25.         index = nColumn;  
  26.         printf("查詢到%d記錄\n",nRow);  
  27.           
  28.         for(i=0;i<nRow;i++)  
  29.         {  
  30.             for(j=0;j<nColumn;j++)  
  31.             {  
  32.                 printf("字段名稱:%s,字段值:%s\n",dbResult[j],dbResult[index]);  
  33.                 index++;  
  34.             }  
  35.             printf("\n");  
  36.         }  
  37.     }  
  38.       
  39.     //釋放char**查詢結果  
  40.     sqlite3_free_table(dbResult);   
  41.       
  42.     sqlite3_close(db);  
  43.       
  44.     return 0;  
  45. }  


上述使用的方法適用於大多數數據庫需求,但是不能適用於二進制數據,操作二進制數據方法需要用到一個數據類型sqlite3_stmt *,該數據類型記錄了一個"sql語句",這里的sql語句是解析后的,用sqlite自己標記記錄的內部數據結構,並不是我們熟悉的sql語句

數據插入到 sqlite3_stmt結構里可不能直接memcpy,也不能像std::string那樣用+號,必須用sqlite提供的
函數來插入。

假設有創建一張表如下
CREATE TABLE test2(ID INTEGER,file_content BLOB)

首先聲明 sqlite3_stmt *stat; 然后將一個sql語句解析到stat結構里去
sqlite3_prepare(db,"INSERT INTO test2(ID,file_content) VALUES(10,?)",-1,&stat,0);
這里sql語句中有個?號,在該函數里,?表示一個未定的值
參數3:表示前面sql語句的長度,如果小於0,sqlite會自動計算它的長度
參數4:sqlite3_stat指針的指針,解析后的sql語句就放在該結構里
參數5:一般設為0

返回值為SQLITE_OK且stat不為NULL,表示成功,當prepare成功后,開始查詢數據
int result = sqlite3_step(stat);
該值返回SQLITE_ROW 表示成功

可以循環執行sqlite3_step函數,一次step查詢出一條記錄,直到返回值不為SQLITE_ROW
然后開始獲取第一個字段:ID值,ID是個整數,使用如下操作
int id = sqlite3_column_int(stat,0); //0表示第1字段
下面獲取file_content的值,因為file_content是二進制,因此需要得到它的指針,還有長度
const void * pFileContent = sqlite3_column_blob(stat,1);
int len = sqlite3_column_bytes(stat,1);
把 pFileContent內容保存后,要釋放sqlite3_stmt結構
sqlite3_finalize(stat);

如果需要重復使用 sqlite3_prepare解析好的sqlite3_stmt結構,使用 sqlite3_reset函數
result = sqlite3_reset(stat);
這樣,stat結構又成為sqlite3_prepare完成時的狀態

sqlite 數據庫事務處理

如果需要同步刪除很多數據,可以將它們做成一個統一的事務,通常sqlite3_exec就是一次事務,假設要刪除1W條記錄,sqlite就做了1W次,開始事務->刪除數據->提交事務,這個操作很慢,我們可以將同類操作作成一個事物,如果操作錯誤,還可以回滾事務

事務的操作沒有特別的接口函數,只是普通的sql語句
int result;
result = sqlite3_exec(db,"begin transtraction",0,0,&zErrorMsg);
result = sqlite3_exec(db,"commit transtraction",0,0,&zErrorMsg);
result = sqlite3_exec(db,"rollback transtraction",0,0,&zErrorMsg);

 sqlite3 錯誤編碼如下:

[cpp]  view plain copy
  1. #define SQLITE_OK           0   /* Successful result */  
  2. #define SQLITE_ERROR        1   /* SQL error or missing database */  
  3. #define SQLITE_INTERNAL     2   /* An internal logic error in SQLite */  
  4. #define SQLITE_PERM         3   /* Access permission denied */  
  5. #define SQLITE_ABORT        4   /* Callback routine requested an abort */  
  6. #define SQLITE_BUSY         5   /* The database file is locked */  
  7. #define SQLITE_LOCKED       6   /* A table in the database is locked */  
  8. #define SQLITE_NOMEM        7   /* A malloc() failed */  
  9. #define SQLITE_READONLY     8   /* Attempt to write a readonly database */  
  10. #define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite_interrupt() */  
  11. #define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */  
  12. #define SQLITE_CORRUPT     11   /* The database disk image is malformed */  
  13. #define SQLITE_NOTFOUND    12   /* (Internal Only) Table or record not found */  
  14. #define SQLITE_FULL        13   /* Insertion failed because database is full */  
  15. #define SQLITE_CANTOPEN    14   /* Unable to open the database file */  
  16. #define SQLITE_PROTOCOL    15   /* Database lock protocol error */  
  17. #define SQLITE_EMPTY       16   /* (Internal Only) Database table is empty */  
  18. #define SQLITE_SCHEMA      17   /* The database schema changed */  
  19. #define SQLITE_TOOBIG      18   /* Too much data for one row of a table */  
  20. #define SQLITE_CONSTRAINT  19   /* Abort due to contraint violation */  
  21. #define SQLITE_MISMATCH    20   /* Data type mismatch */  
  22. #define SQLITE_MISUSE      21   /* Library used incorrectly */  
  23. #define SQLITE_NOLFS       22   /* Uses OS features not supported on host */  
  24. #define SQLITE_AUTH        23   /* Authorization denied */  
  25. #define SQLITE_ROW         100  /* sqlite_step() has another row ready */  
  26. #define SQLITE_DONE        101  /* sqlite_step() has finished executing */  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM