什么是SQLite?
數(shù)據(jù)庫存儲數(shù)據(jù)的步驟
●SQLite是一款輕型的嵌入式數(shù)據(jù)庫,它占用資源非常的低,在嵌入式設(shè)備中,可能只需要幾百K的內(nèi)存就夠了.它的處理速度比Mysql、PostgreSQL這兩款著名的數(shù)據(jù)庫都還快
什么是數(shù)據(jù)庫?
●數(shù)據(jù)庫(Database)是按照數(shù)據(jù)結(jié)構(gòu)來組織、存儲和管理數(shù)據(jù)的倉庫
●數(shù)據(jù)庫可以分為2大種類: 關(guān)系型數(shù)據(jù)庫(主流), 對象型數(shù)據(jù)庫
●常用關(guān)系型數(shù)據(jù)庫:
???? PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase
???? 嵌入式\移動客戶端:SQLite
如何存儲數(shù)據(jù)?
數(shù)據(jù)庫的存儲結(jié)構(gòu)和excel很像,以表(table)為單位.
數(shù)據(jù)庫存儲數(shù)據(jù)的步驟 :
1. 新建一張表(table); 2. 添加多個字段(column,列,屬性);? 3. 添加多行記錄(row,record,每行存放多個字段對應(yīng)的值)
SQL語句
如何在程序運(yùn)行過程中操作數(shù)據(jù)庫中的數(shù)據(jù),那得先學(xué)會使用SQL語句
●什么是SQL?
????? ●SQL(structured query language):結(jié)構(gòu)化查詢語言
?????? ●SQL是一種對關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行定義和操作的語言
?????? ●SQL語言簡潔,語法簡單,好學(xué)好用
●什么是SQL語句?
???? ●使用SQL語言編寫出來的句子\代碼,就是SQL語句
????? ●在程序運(yùn)行過程中,要想操作(增刪改查,CRUD)數(shù)據(jù)庫中的數(shù)據(jù),必須使用SQL語句
●SQL語句的特點 :
? 1. 不區(qū)分大小寫(比如數(shù)據(jù)庫認(rèn)為user和UsEr是一樣的); ? ?? 2. 每條語句都必須以分號;結(jié)尾
●SQL中的常用關(guān)鍵字有
●select、insert、update、delete、from、create、where、desc、order、by、group、
table、alter、view、index等等
●數(shù)據(jù)庫中不可以使用關(guān)鍵字來命名表、字段
SQL語句的種類
●數(shù)據(jù)定義語句: (DDL:Data Definition Language)
? ? ? 包括create和drop等操作;?? 例如:在數(shù)據(jù)庫中創(chuàng)建新表或刪除表(create table或drop table)
●數(shù)據(jù)操作語句(DML:Data Manipulation Language)
???? 包括insert、update、delete等操作(添加、修改(更新)、刪除表中的數(shù)據(jù))
●數(shù)據(jù)查詢語句(DQL:Data Query Language)
???? 可以用于查詢獲得表中的數(shù)據(jù),? 關(guān)鍵字select是DQL(也是所有SQL)用得最多的操作
???? 其他DQL常用的關(guān)鍵字有where,order by,group by和having
創(chuàng)表
create table if not exists? 表名(字段名1? 字段類型1, 字段名2 字段類型2,..... );
示例:?
create table if not exists t_student (id integer, name text, age inetger, score real) ;
? 字段類型
一般數(shù)據(jù)采用的固定的靜態(tài)數(shù)據(jù)類型,而SQLite采用的是動態(tài)數(shù)據(jù)類型,會根據(jù)存入值自動判斷。SQLite的數(shù)據(jù)存儲類型有: integer (有符號整形), real (浮點值,以8字節(jié)IEEE浮點數(shù)存放), text(文本字符串,使用數(shù)據(jù)庫編碼UTF-8,UTF-16BE或者UTF-16LE存放), blob(是一個數(shù)據(jù)塊,完全按照輸入存放; 二進(jìn)制數(shù)據(jù),比如: 文件) 布爾類型 Sqlite沒有單獨的布爾存儲類型,它使用INTEGER作為存儲類型,0為false,1為true
從上可以看出存儲類比數(shù)據(jù)類型更一般化。比如INTEGER存儲類,包括6中不同長度的不同整形數(shù)據(jù)類型,這在磁盤上造成了差異。但是只要INTEGER值被從磁盤讀出進(jìn)入到內(nèi)存進(jìn)行處理,它們被轉(zhuǎn)換成最一般的數(shù)據(jù)類型(8-字節(jié)有符號整形)。
SQLite是無類型的. 這意味著你可以保存任何類型的數(shù)據(jù)到你所想要保存的任何表的任何列中, 無論這列聲明的數(shù)據(jù)類型是什么(只有自動遞增Integer Primary Key才有用). 對于SQLite來說對字段不指定類型是完全有效的.
建表時聲明啥類型或者不聲明類型都可以,也就意味著創(chuàng)表語句可以這么寫:
create table if not exists? t_student(name, age);
CREATE TABLE ex2( a?? VARCHAR(10),?? b? NVARCHAR(15),? c?? TEXT,? d?? INTEGER,e?? FLOAT,f??? BOOLEAN,g ? ? CLOB,h???? BLOB,i ?? TIMESTAMP,j??? NUMERIC(10,5),k??? VARYING?? CHARACTER (24),l??? NATIONAL?? VARYING?? CHARACTER(16));
注意: 為了保持良好的編程規(guī)范、方便程序員之間的交流,編寫建表語句的時候最好加上每個字段的具體類型(否則容易挨揍,哈哈)
額外了解:
char、varchar、text和nchar、nvarchar、ntext的區(qū)別
1、CHAR。CHAR存儲定長數(shù)據(jù)很方便,CHAR字段上的索引效率級高,比如定義char(10),那么不論你存儲的數(shù)據(jù)是否達(dá)到了10個字節(jié),都要占去10個字節(jié)的空間,不足的自動用空格填充。
2、VARCHAR。存儲變長數(shù)據(jù),但存儲效率沒有CHAR高。如果一個字段可能的值是不固定長度的,我們只知道它不可能超過10個字符,把它定義為VARCHAR(10)是最合算的。VARCHAR類型的實際長度是它的值的實際長度+1。為什么“+1”呢?這一個字節(jié)用于保存實際使用了多大的長度。從空間上考慮,用varchar合適;從效率上考慮,用char合適,關(guān)鍵是根據(jù)實際情況找到權(quán)衡點。3、TEXT。text存儲可變長度的非Unicode數(shù)據(jù),最大長度為2^31-1(2,147,483,647)個字符。4、NCHAR、NVARCHAR、NTEXT。這三種從名字上看比前面三種多了個“N”。它表示存儲的是Unicode數(shù)據(jù)類型的字符。我們知道字符中,英文字符只需要一個字節(jié)存儲就足夠了,但漢字眾多,需要兩個字節(jié)存儲,英文與漢字同時存在時容易造成混亂,Unicode字符集就是為了解決字符集這種不兼容的問題而產(chǎn)生的,它所有的字符都用兩個字節(jié)表示,即英文字符也是用兩個字節(jié)表示。nchar、nvarchar的長度是在1到4000之間。和char、varchar比較起來,nchar、nvarchar則最多存儲4000個字符,不論是英文還是漢字;而char、varchar最多能存儲8000個英文,4000個漢字。可以看出使用nchar、nvarchar數(shù)據(jù)類型時不用擔(dān)心輸入的字符是英文還是漢字,較為方便,但在存儲英文時數(shù)量上有些損失。
所以一般來說,如果含有中文字符,用nchar/nvarchar,如果純英文和數(shù)字,用char/varchar。
刪表
格式 : drop table if exists表名;
示例:???? drop? table ? if? exists ? t_student ;
插入數(shù)據(jù)(insert)
格式:?? insert into表名(字段1,字段2, ...)values(字段1的值,字段2的值, ...) ;
示例 :
insert?? into??? t_student (name, age)? values? (‘mj’, 10) ;
注意:? 數(shù)據(jù)庫中的字符串內(nèi)容應(yīng)該用單引號’括住
更新數(shù)據(jù)(update)
格式: update表名set字段1=字段1的值,字段2=字段2的值, ... ;
示例:
update t_student set? name=‘jack’, age=20 ;
注意:? 上面的示例會將t_student表中所有記錄的name都改為jack,age都改為20
刪除數(shù)據(jù)(delete)
格式: delete from 表名;
示例:??? delete from?? t_student ;
注意:???? 上面的示例會將t_student表中所有記錄都刪掉
條件語句: 如果只想更新或者刪除某些固定的記錄,那就必須在DML語句后加上一些條件
條件語句格式:
????? where 字段?? =?? 某個值;?????? //不能使用兩個=
????? where 字段?? is? 某個值 ;????? // is 相當(dāng)于 =
????? where 字段?? != 某個值
????? where 字段? is not 某個值;??? // is not 相當(dāng)于!=
? ? ? where 字段? > 某個值;
? ? ? where 字段1 = 某個值? and 字段2 > 某個值;? ??? // and相當(dāng)于C語言中的&&
?????? where字段1=某個值or字段2=某個值;?????????????? // or相當(dāng)于C語言中的||
???? 條件語句練習(xí)
示例: 將t_student表中年齡大于10并且姓名不等于jack的記錄,年齡都改為5
update t_student set age? = 5?? where? age >10?? and?? name !=?? 'jack';?
刪除t_student表中年齡小于等于10或者年齡大于30的記錄
delete from t_student where age <= 10 or age > 30;
猜猜下面語句的作用
update?? t_student? set? score = age where? name=‘jack’ ; // (將t_student表中名字等于jack的記錄,score字段的值 都改為age字段的值)
DQL語句
格式:? select字段1,字段2, ...from表名;???? //查詢表中的某些個字段
?????????? select?? *from表名;?? //查詢所有的字段
●示例:??
? ???? select age ,name from? t_student;
??????? select * from? t_studnet;
?????? select *from t_student where age > 10 ;? //條件查詢
起別名:
格式(字段和表都可以起別名)
????? select 字段1 別名, 字段2 別名, ......from? 表名 別名;
?????? select字段1別名,字段2as別名,...from表名as別名;
?????? select別名.字段1,別名.字段2, ...from表名 別名;
示例:
給name起個叫做myname的別名,給age起個叫做myage的別名
????????? select name myname,age myage from t_student;
給t_student表起個別名叫做s,利用s來引用表中的字段
????????? select? s.name, s.age? from? t_student s ;
計算記錄的數(shù)量
格式: select count (字段) from 表名;? // 某個字段記錄的數(shù)據(jù)數(shù)量
????????? select? count (*) from 表名;? //
示例 :? select count(age) from? t_student ;
???????????? select? count( * ) from? t_student?? where? score>=60;
排序
查詢出來的結(jié)果可以用order by進(jìn)行排序
??????? select? * from? t_student? order by? 字段;
??????? select *from? t_student?? order by? age ;
默認(rèn)是按照升序排序(由小到大),也可以變?yōu)榻敌?由大到小)
??????? select *from??? t_student???? order?? by ? age?? desc;//降序
???????? select *from?? t_student??? order?? by?? age?? asc;//升序(默認(rèn))
也可以用多個字段進(jìn)行排序
??????? select? *from?? t_student?? order by? age asc, height? desc;
?先按照年齡排序(升序),年齡相等就按照身高排序(降序)
limit
使用limit可以精確的控制查詢結(jié)果的數(shù)量, 比如每天值查詢10條數(shù)據(jù),
格式:? select *from 表名 limit 數(shù)值1, 數(shù)值2;
示例: select *from t_student limit 4, 8;??? // 跳過最前面的4條語句,然后取8條記錄;
limit常用來做分頁查詢,比如每頁固定顯示5條數(shù)據(jù),那么應(yīng)該這樣取數(shù)據(jù)
??????? 第1頁:limit 0, 5
?????? 第2頁:limit 5, 5
??????? 第3頁:limit 10, 5
???????? ...
?????? 第n頁:limit 5*(n-1), 5
簡單約束
建表時可以給特定的字段設(shè)置一些約束條件,常見的約束有
??????? not null:規(guī)定字段的值不能為null
???????? unique:規(guī)定字段的值必須唯一
???????? default:指定字段的默認(rèn)值
(建議:盡量給字段設(shè)定嚴(yán)格的約束,以保證數(shù)據(jù)的規(guī)范性)
●示例
??? create table? t_student (id? integer, name? text not null unique, age integer not null? default 1) ;? //name字段不能為null,并且唯一;??? age字段不能為null,并且默認(rèn)為1
主鍵約束
如果t_student表中就name和age兩個字段,而且有些記錄的name和age字段的值都一樣時,那么就沒法區(qū)分這些數(shù)據(jù),造成數(shù)據(jù)庫的記錄不唯一,這樣就不方便管理數(shù)據(jù)
●良好的數(shù)據(jù)庫編程規(guī)范應(yīng)該要保證每條記錄的唯一性,為此,增加了主鍵約束,也就是說,每張表都必須有一個主鍵,用來標(biāo)識記錄的唯一性
●什么是主鍵
?????? 主鍵(Primary Key,簡稱PK)用來唯一地標(biāo)識某一條記錄
例如t_student可以增加一個id字段作為主鍵,相當(dāng)于人的身份證
??????? 主鍵可以是一個字段或多個字段
主鍵的設(shè)計原則
●主鍵應(yīng)當(dāng)是對用戶沒有意義的●永遠(yuǎn)也不要更新主鍵
●主鍵不應(yīng)包含動態(tài)變化的數(shù)據(jù)●主鍵應(yīng)當(dāng)由計算機(jī)自動生成
主鍵的聲明
在創(chuàng)表的時候用primary key聲明一個主鍵
create?? table ? if?? not ? exists ? t_student (id integer primary key? autoincrement, name text, age integer );?? //integer類型的id作為t_student表的主鍵
外鍵約束
利用外鍵約束可以用來建立表與表之間的聯(lián)系,? 外鍵的一般情況是:一張表的某個字段,引用著另一張表的主鍵字段
新建一個外鍵
create table if not exists t_student (id integer primary key autoincrement, name text, age integer, class_id integer,constraint? fk_student_class?? foreign key?? (class_id)? references?? t_class (id));??? //t_student表中有一個叫做fk_t_student_class_id_t_class_id的外鍵,? 這個外鍵的作用是用t_student表中的class_id字段引用t_class表的id字段
表連接查詢
什么是表連接查詢????? --->?? 需要聯(lián)合多張表才能查到想要的數(shù)據(jù)
表連接的類型:??
??????? 內(nèi)連接:inner join或者join(顯示的是左右表都有完整字段值的記錄)
??????? 左外連接:left outer join(保證左表數(shù)據(jù)的完整性)
●示例: 查詢0316iOS班的所有學(xué)生
? select s.name,s.age ? from? t_student s, t_class?? c ? where?? s.class_id? =? c.id??? and?? c.name =
‘0316iOS’;
????????????????????????????????????? SQLite3編碼
在iOS中使用SQLite3,首先要添加庫文件libsqlite3.dylib和導(dǎo)入主頭文件
創(chuàng)建、打開、關(guān)閉數(shù)據(jù)庫
●創(chuàng)建或打開數(shù)據(jù)庫
// path是數(shù)據(jù)庫文件的存放路徑
sqlite3*db = NULL;?? // sqlite3 *db:一個打開的數(shù)據(jù)庫實例
int result =sqlite3_open([path UTF8String], &db); //sqlite3_open()將根據(jù)文件路徑打開數(shù)據(jù)庫,如果不存在,則會創(chuàng)建一個新的數(shù)據(jù)庫。如果result等于常量SQLITE_OK,則表示成功打開數(shù)據(jù)庫;? UTF8String 數(shù)據(jù)庫文件的路徑必須以C字符串(而非NSString)傳入
●關(guān)閉數(shù)據(jù)庫:sqlite3_close(db);
執(zhí)行不返回數(shù)據(jù)的SQL語句
執(zhí)行創(chuàng)表語句
char *errorMsg = NULL;//用來存儲錯誤信息
char *sql = "create table if not exists t_person(id integer primary key autoincrement, name
text, age integer);";
int result =sqlite3_exec(db, sql, NULL, NULL, &errorMsg); // sqlite3_exec()可以執(zhí)行任何SQL語句,比如創(chuàng)表、更新、插入和刪除操作。但是一般不用它執(zhí)行查詢語句,因為它不會返回查詢到的數(shù)據(jù)
sqlite3_exec()還可以執(zhí)行的語句:
(1)開啟事務(wù):begin transaction;
(2)回滾事務(wù):rollback;
(3)提交事務(wù):commit;
帶占位符插入數(shù)據(jù)
char *sql = "insert into t_person(name, age) values(?, ?);";sqlite3_stmt*stmt;
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) ==SQLITE_OK) {
sqlite3_bind_text(stmt, 1, "母雞", -1, NULL);
sqlite3_bind_int(stmt, 2, 27);
}///? sqlite3_prepare_v2()返回值等于SQLITE_OK,說明SQL語句已經(jīng)準(zhǔn)備成功,沒有語法問題
if (sqlite3_step(stmt) !=SQLITE_DONE) {
NSLog(@"插入數(shù)據(jù)錯誤");
}sqlite3_finalize(stmt);
帶占位符插入數(shù)據(jù)
sqlite3_bind_text():大部分綁定函數(shù)都只有3個參數(shù)
(1)第1個參數(shù)是sqlite3_stmt *類型
(2)第2個參數(shù)指占位符的位置,第一個占位符的位置是1,不是0
(3)第3個參數(shù)指占位符要綁定的值
(4)第4個參數(shù)指在第3個參數(shù)中所傳遞數(shù)據(jù)的長度,對于C字符串,可以傳遞-1代替
字符串的長度
(5)第5個參數(shù)是一個可選的函數(shù)回調(diào),一般用于在語句執(zhí)行后完成內(nèi)存清理工作
●sqlite_step():執(zhí)行SQL語句,返回SQLITE_DONE代表成功執(zhí)行完畢
●sqlite_finalize():銷毀sqlite3_stmt *對象
查詢數(shù)據(jù)
char *sql = "select id,name,age from t_person;";
sqlite3_stmt*stmt;
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) ==SQLITE_OK) {
while (sqlite3_step(stmt) ==SQLITE_ROW) {
int _id =sqlite3_column_int(stmt,0);
char *_name = (char *)sqlite3_column_text(stmt,1);
NSString *name = [NSStringstringWithUTF8String:_name];
int _age =sqlite3_column_int(stmt,2);
NSLog(@"id=%i, name=%@, age=%i", _id, name, _age);
}
}
sqlite3_finalize(stmt);
●代碼解析
●sqlite3_step()返回SQLITE_ROW代表遍歷到一條新記錄
●sqlite3_column_*()用于獲取每個字段對應(yīng)的值,第2個參數(shù)是字段的索引,從0開始
下面以具體的代碼演示 SQLite的使用
#import "HMViewController.h"
#import <sqlite3.h>
#import "HMShop.h"
@interface HMViewController () <UITableViewDataSource,UITableViewDelegate, UISearchBarDelegate>
@property (weak, nonatomic) IBOutlet UITextField *nameField;
@property (weak, nonatomic) IBOutlet UITextField *priceField;/** 數(shù)據(jù)庫對象實例 */
@property (nonatomic, assign) sqlite3 *db;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
- (IBAction)insert;
@property (nonatomic, strong) NSMutableArray *shops;
@end
@implementation HMViewController
- (NSMutableArray *)shops{
???? if (!_shops) {
????????? self.shops = [[NSMutableArray alloc] init];
?????? }
?????? return _shops;
}
- (void)viewDidLoad{
??????? [super viewDidLoad];
??????? // 增加搜索框
????????? UISearchBar *searchBar = [[UISearchBar alloc] init];
?????????? searchBar.frame = CGRectMake(0, 0, 320, 44);
?????????? searchBar.delegate = self;
????????????? self.tableView.tableHeaderView = searchBar;
??????? // 初始化數(shù)據(jù)庫
?????????????? [self setupDb];
????? // 查詢數(shù)據(jù)
????????? [self setupData];
???????? // 關(guān)閉數(shù)據(jù)庫
??????? //? ? sqlite3_close();
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.shops removeAllObjects];
NSString *sql = [NSString stringWithFormat:@"SELECT name,price FROM t_shop WHERE name LIKE '%%%@%%' OR? price LIKE '%%%@%%' ;", searchText, searchText];
// stmt是用來取出查詢結(jié)果的
sqlite3_stmt *stmt = NULL;
// 準(zhǔn)備
int status = sqlite3_prepare_v2(self.db, sql.UTF8String, -1, &stmt, NULL);
if (status == SQLITE_OK) { // 準(zhǔn)備成功 -- SQL語句正確
while (sqlite3_step(stmt) == SQLITE_ROW) { // 成功取出一條數(shù)據(jù)
const char *name = (const char *)sqlite3_column_text(stmt, 0);
const char *price = (const char *)sqlite3_column_text(stmt, 1);
HMShop *shop = [[HMShop alloc] init];
shop.name = [NSString stringWithUTF8String:name];
shop.price = [NSString stringWithUTF8String:price];
[self.shops addObject:shop];
}
}
[self.tableView reloadData];
}
/**
查詢數(shù)據(jù)
*/
- (void)setupData{
const char *sql = "SELECT name,price FROM t_shop;";
// stmt是用來取出查詢結(jié)果的
sqlite3_stmt *stmt = NULL;
// 準(zhǔn)備
int status = sqlite3_prepare_v2(self.db, sql, -1, &stmt, NULL);
if (status == SQLITE_OK) { // 準(zhǔn)備成功 -- SQL語句正確
while (sqlite3_step(stmt) == SQLITE_ROW) { // 成功取出一條數(shù)據(jù)
const char *name = (const char *)sqlite3_column_text(stmt, 0);
const char *price = (const char *)sqlite3_column_text(stmt, 1);
HMShop *shop = [[HMShop alloc] init];
shop.name = [NSString stringWithUTF8String:name];
shop.price = [NSString stringWithUTF8String:price];
[self.shops addObject:shop];
}
}
}
/**
初始化數(shù)據(jù)庫
*/
- (void)setupDb
{
// 打開數(shù)據(jù)庫(連接數(shù)據(jù)庫)
NSString *filename = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"shops.sqlite"];
// 如果數(shù)據(jù)庫文件不存在, 系統(tǒng)會自動創(chuàng)建文件自動初始化數(shù)據(jù)庫
int status = sqlite3_open(filename.UTF8String, &_db);
if (status == SQLITE_OK) { // 打開成功
NSLog(@"打開數(shù)據(jù)庫成功");
// 創(chuàng)表
const char *sql = "CREATE TABLE IF NOT EXISTS t_shop (id integer PRIMARY KEY, name text NOT NULL, price real);";
char *errmsg = NULL;
sqlite3_exec(self.db, sql, NULL, NULL, &errmsg);
if (errmsg) {
NSLog(@"創(chuàng)表失敗--%s", errmsg);
}
} else { // 打開失敗
NSLog(@"打開數(shù)據(jù)庫失敗");
}
}
#pragma mark 添加數(shù)據(jù)
- (IBAction)insert {
NSString *sql = [NSString stringWithFormat:@"INSERT INTO t_shop(name, price) VALUES ('%@', %f);", self.nameField.text, self.priceField.text.doubleValue];
sqlite3_exec(self.db, sql.UTF8String, NULL, NULL, NULL);
// 刷新表格
HMShop *shop = [[HMShop alloc] init];
shop.name = self.nameField.text;
shop.price = self.priceField.text;
[self.shops addObject:shop];
[self.tableView reloadData];
}
#pragma mark - 數(shù)據(jù)源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.shops.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"shop";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
cell.backgroundColor = [UIColor grayColor];
}
HMShop *shop = self.shops[indexPath.row];
cell.textLabel.text = shop.name;
cell.detailTextLabel.text = shop.price;
return cell;
}
@end
??????????????????????????????????????? SQLite函數(shù)總結(jié)
1.打開數(shù)據(jù)庫
int sqlite3_open(
const char *filename,? // 數(shù)據(jù)庫的文件路徑
sqlite3 **ppDb? ? ? ? ? // 數(shù)據(jù)庫實例
);
2.執(zhí)行任何SQL語句
int sqlite3_exec(
sqlite3*,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 一個打開的數(shù)據(jù)庫實例
const char *sql,? ? ? ? ? ? ? ? ? ? ? ? ? // 需要執(zhí)行的SQL語句
int (*callback)(void*,int,char**,char**),? // SQL語句執(zhí)行完畢后的回調(diào)
void *,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 回調(diào)函數(shù)的第1個參數(shù)
char **errmsg? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 錯誤信息
);
3.檢查SQL語句的合法性(查詢前的準(zhǔn)備)
int sqlite3_prepare_v2(
sqlite3 *db,? ? ? ? ? ? // 數(shù)據(jù)庫實例
const char *zSql,? ? ? // 需要檢查的SQL語句
int nByte,? ? ? ? ? ? ? // SQL語句的最大字節(jié)長度
sqlite3_stmt **ppStmt,? // sqlite3_stmt實例,用來獲得數(shù)據(jù)庫數(shù)據(jù)
const char **pzTail
);
4.查詢一行數(shù)據(jù)
int sqlite3_step(sqlite3_stmt*); // 如果查詢到一行數(shù)據(jù),就會返回SQLITE_ROW
5.利用stmt獲得某一字段的值(字段的下標(biāo)從0開始)
double sqlite3_column_double(sqlite3_stmt*, int iCol);? // 浮點數(shù)據(jù)
int sqlite3_column_int(sqlite3_stmt*, int iCol); // 整型數(shù)據(jù)
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); // 長整型數(shù)據(jù)
const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 二進(jìn)制文本數(shù)據(jù)
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);? // 字符串?dāng)?shù)據(jù)
錯誤之處歡迎,