美文网首页
未命名标题shu

未命名标题shu

作者: 洋洋丝 | 来源:发表于2017-06-18 22:01 被阅读9次

数据表定义语句(DDL)

创建表:

create table if not exists <biaoming> (id integer primary key autoincrement,name text not NULL, age integer default 60)

删除表:

drop table if exists <biaoming>

更改表名:

alter table <biaoming> rename to <xinbiaoming>

给表增加列:

alter table <biaoming> add column <lieming> name text <zhibiaofu>

数据表操作语句(DML)

增加:

insert into <biaoming> (name, age,score) values {'xiaowang',90,80}

修改:

update <> set name = 'xiaohong',age = 20

update <> set score = 30 where id > 30

删除:

delete from <> where age is 18

DQL:查询语句

select name, age from <>

select * from <>

统计:

记录所有age不为空的个数(记录)select count(age) from <>

记录某个字段平均值 select avg(age) from <>

求和:sum zuida:max zuixiao:min

排序:

select *from <> order by score ASC(升序) 或者用 DESC(降序)

select *from <> order by score ASC,age DESC

分页:

select * from <> limit 1,3 1表示跳过1条,3表示跳过3条

多表查询:

OC中代码:

创建数据库

    //参数1.数据库文件的路径 2.数据库对象,要打开的数据库
    //返回值表示操作的状态码
    int result = sqlite3_open(filename, &_db);
    if (result == SQLITE_OK)
    {
        NSLog(@"数据库打开成功");
        return YES;
    }
    else
    {
        NSLog(@"数据库打开失败");
        //sqlite3_close 关闭数据库的方法
        sqlite3_close(_db);
        return NO;
    }

创建表
    char *error = nil;
    //sqlite3_exec对数据库的操作:创建表,增删改,都建议用这个方法,查建议用其他的
    //参数 1.数据库对象 2.sql语句 3.回调函数nil 4.回调函数的参数nil
    if (sqlite3_exec(_db, [str UTF8String], nil, nil, &error)==SQLITE_OK)
    {
        NSLog(@"创建表成功");
    }
    else
    {
        NSLog(@"创建表失败:%s",error);
    }

增删改查

//第一种方式sqlite3_exec

//sql为相关的增删改语句
sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK

//另一种方式,预处理语句sqlite3_prepare_v2

let prepareSql = "INSERT INTO \(tableName)(\(columnNames)) values (\(valuesStr))"

        var stmt: COpaquePointer = nil

        // 预处理SQL语句, 并生成 "语句句柄" , 后续会使用这样的语句句柄绑定数值, 并执行

        if sqlite3_prepare_v2(db, prepareSql, -1, &stmt, nil) != SQLITE_OK
        {
            print("预处理失败")
            // 释放语句资源
            sqlite3_finalize(stmt)
            return false
        }

        var index: Int32 = 1

        for obj in values
        {

            if obj is Int
            {
                let temp: sqlite_int64 = obj as! sqlite_int64
                sqlite3_bind_int64(stmt, index, temp)
            } else if obj is Double
            {
                sqlite3_bind_double(stmt, index, obj as! Double)
            }else if obj is String
            {
                /**
                 第5个参数
                 此参数有两个常数,SQLITE_STATIC告诉sqlite3_bind_text函数字符串为常量,可以放心使用;
                 而SQLITE_TRANSIENT会使得sqlite3_bind_text函数对字符串做一份拷贝。
                一般使用这两个常量参数来调用sqlite3_bind_text。
                 */
                sqlite3_bind_text(stmt, index, obj as! String, -1, SQLITE_TRANSIENT)

            }else {
                continue
            }

            index++

        }

        var result: Bool = false
        if sqlite3_step(stmt) == SQLITE_DONE
        {
            print("插入成功")
            result = true
        }else
        {
            print("插入失败")
            result = false

        }

        // 将语句复位
        if sqlite3_reset(stmt) != SQLITE_OK
        {
            print("复位失败")
            result = false
        }

        // 释放语句
        sqlite3_finalize(stmt)

        return result

处理大数据耗时问题

插入10000条数据

sqlite_exec 10000 5.8080689907074
sqlite_prepare 10000 5.93309998512268
sqlite_prepare 分解后, 准备1次, 多次绑定/重置, 一次释放 5.11254101991653
分析结果
所以: 如果执行单条语句的话, 两者效率几乎一致
如果执行多条语句, 建议使用"准备语句"
两者区别:
sqlite_exec 函数是对"准备语句"的封装 (预处理语句->绑定参数->执行语句->重置语句->释放语句)
如果需要绑定二进制数据, 就必须要使用"准备语句了"
sqlite_exec 用法相对简单

整体耗时, 依然达到5秒左右, 非常庞大
原因: 因为sqlite3_exec, 或者 sqlite3_step 执行语句时, 都会自动开启事务-> 执行语句 -> 提交事务 这样的流程, 所以造成了, 多次开启和提交事务, 这个是非常耗时的操作
解决方案: 手动开启和提交事务即可, 这样 系统就不会自动开启事务和提交事务了

代码:


XMGSQLTool.shareInstance.beginTransaction()
for _ in 0...9999 {
stu.insertStudent()
}
XMGSQLTool.shareInstance.commitTransaction()

/** 开启事务 */
    func beginTransaction() -> Bool
    {
        let sql = "BEGIN TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

    /** 提交事务 */
    func commitTransaction() -> Bool
    {
        let sql = "COMMIT TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

/** 回滚事务*/
    func rollBackTransaction() -> Bool
    {
        let sql = "ROLLBACK TRANSACTION"
        return (sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK)
    }

开启事务BEGIN TRANSACTION
提交事务COMMIT TRANSACTION
回滚事务ROLLBACK TRANSACTION

查询的两种方式

        let selectSql = "select * from t_student"

        // 方式1:
        // 参数1: 一个打开的数据库
        // 参数2: 需要执行的SQL语句
        // 参数3: 查询结果回调(执行0次或多次)
            // 参数1: 参数4的值
            // 参数2: 列的个数
            // 参数3: 结果值的数组
            // 参数4: 所有列的名称数组
            // 返回值: 0代表继续执行一致到结束, 1代表执行一次
        // 参数4: 回调函数的第一个值
        // 参数5: 错误信息
        sqlite3_exec(db, selectSql, { (parameter: UnsafeMutablePointer<Void>, columnCount: Int32, values: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>, columnNames: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>) -> Int32 in

                let count = Int(columnCount)
                for i: Int in 0..<count
                {
                    let column = columnNames[i]
                    let columnStr = String(CString: column, encoding: NSUTF8StringEncoding)

                    let value = values[i]
                    let valueStr = String(CString: value, encoding: NSUTF8StringEncoding)
                    print(columnStr! + "= " + valueStr!)
                }

                return 0
            }, nil, nil)

            // 方式2:
//        var stmt: COpaquePointer = nil
//        if sqlite3_prepare(db, selectSql, -1, &stmt, nil) != SQLITE_OK
//        {
//            print("预处理失败")
//            return
//        }
//
//        // 因为查询语句中没有占位?, 所以, 可以省略"绑定步骤"
//        // 执行语句
//        // sqlite3_step, 当使用这个方法时, 执行完毕后, 会自动跳到结果集的下一行, 如果依然有记录就返回SQLITE_ROW,
//       while sqlite3_step(stmt) == SQLITE_ROW
//       {
//        let columnCount = sqlite3_column_count(stmt)
//
//        for i in 0..<columnCount
//        {
//
//            //  获取列的类型
//            let type = sqlite3_column_type(stmt, i)
//
//            if type == SQLITE_TEXT
//            {
//                let text = UnsafePointer<Int8>(sqlite3_column_text(stmt, i))
//                let str = String(CString: text, encoding: NSUTF8StringEncoding)
//                print(str)
//            }
//
//        }
//
//        }
//
//        sqlite3_finalize(stmt)

FMDB使用:

优势:1.封装 2.提供了多线程访问数据方式

三个主要的类:

FMDatabase:是一个提供 SQLite 数据库的类,用于执行 SQL 语句。
FMResultSet:用在 FMDatabase 中执行查询的结果的类。
FMDatabaseQueue:在多线程下查询和更新数据库用到的类。

数据库创建

FMDatabase 是通过一个 SQLite 数据库文件路径创建的,此路径可以是以下三者之一:

一个文件的系统路径。磁盘中可以不存在此文件,因为如果不存在会自动为你创建。
一个空的字符串 @""。会在临时位置创建一个空的数据库,当 FMDatabase 连接关闭时,该数据库会被删除。
NULL。会在内存中创建一个数据库,当 FMDatabase 连接关闭时,该数据库会被销毁。

推荐文章:

[an example]http://www.jianshu.com/p/d60ee3c85d63

相关文章

  • 未命名标题shu

    数据表定义语句(DDL) 创建表: create table if not exists (id intege...

  • 未命名

    “打开文档,默认的标题是未命名,因此才有了那么多未命名的故事。想要述说的文字可以这么近,但是触不到的心总是那么远。...

  • 未命名的标题

    你眼前的世界,不一定是真的,障眼法太多,你选择相信你所信的,它必然会是真的。 头脑意识在掌控你的所作所为,下一秒的...

  • 人生总是如此难过的吗

    未命名A:人生总是如此难过的吗?未命名B:是的,长大后会更加难过的。未命名A:不能积极一点、快乐一点吗?未命名B:...

  • 如何让搜索引擎搜索到自己的网站

    页面头部的优化: 1.每个网页的标题都要有,有的网站一看,浏览器显示“未命名标题”,这样的网站是失败的,起码每个页...

  • shu

    如果你可以看到我坐在這裡 感受偶爾吹過來的春風 如果想象得到 那邊便是愜意 很獨享的那種怡然 別人可以說你不懂事...

  • tab点击,图片放大缩小动画

    项目中这次改版应产品要求加入tabbar点击做放大缩小动画,只改变图片,标题不做动画。先看效果图未命名.gif D...

  • 第10课 静态变量与静态方法

    作业要求为Post类增加一个静态变量,命名为DEFAULT_TITLE,表示默认的标题,初始化为“这是一篇未命名博...

  • 未命名

    “打开文档,默认的标题是未命名,想要述说的文字可以这么近,但是触不到的心总是那么远。叶子都掉落了,请努力让自己更好...

  • Shu Rui

    今天好像做了 挺值得纪念的事。 这种疼痛的幸福, 有一种酥爽的感觉。 何淑睿, 我把你的名字纹在我的手上 逗波流转...

网友评论

      本文标题:未命名标题shu

      本文链接:https://www.haomeiwen.com/subject/tdjwqxtx.html