金沙棋牌app手机下载

当前位置:金沙棋牌 > 金沙棋牌app手机下载 > 语句查询执行顺序,sql语句查询执行顺序金沙棋

语句查询执行顺序,sql语句查询执行顺序金沙棋

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-11-22 11:09

注意:笔者经过实验和查阅资料,已在原作基础上做了部分更改。更改不代表原作观点,查看原作请点击下方链接。

前言

数据库的查询执行,毋庸置疑是程序员必备技能之一,然而数据库查询执行的过程绚烂多彩,却是很少被人了解,今天哥哥要带你装逼带你飞,深入一下这sql查询的来龙去脉,为查询的性能优化处理打个基础,或许面试你也会遇到,预防不跪还是看看吧。

这篇博客,摒弃查询优化性能,作为其基础,只针对查询流程讲解剖析。

本片博客阐述的过程为

1、上一个标识过的sql语句,展示查询执行的流程

2、上一个流程图

3、做一个例子逐步深入分析,帮助理解

4、做一个装逼的总结


原文出处:

作者:张龙豪

链接:

sql查询语句的处理步骤,代码清单

--查询组合字段
(5)select (5-2) distinct(5-3) top(<top_specification>)(5-1)<select_list>
--连表
(1)from (1-J)<left_table><join_type> join <right_table> on <on_predicate>
        (1-A)<left_table><apply_type> apply <right_table_expression> as <alias>
        (1-P)<left_table> pivot (<pivot_specification>) as <alias>
        (1-U)<left_table> unpivot (<unpivot_specification>) as <alias>
--查询条件
(2)where <where_pridicate>
--分组
(3)group by <group_by_specification>
--分组条件
(4)having<having_predicate>
--排序
(6)order by<order_by_list>

说明:

1、顺序为有1-6,6个大步骤,然后细分,5-1,5-2,5-3,由小变大顺序,1-J,1-A,1-P,1-U,为并行次序。如果不够明白,接下来我在来个流程图看看。

2、执行过程中也会相应的产生多个虚拟表(下面会有提到),以配合最终的正确查询。

1 简介

前言

数据库的查询执行,毋庸置疑是程序员必备技能之一,然而数据库查询执行的过程绚烂多彩,却是很少被人了解,今天哥哥要带你装逼带你飞,深入一下这sql查询的来龙去脉,为查询的性能优化处理打个基础,或许面试你也会遇到,预防不跪还是看看吧。

这篇博客,摒弃查询优化性能,作为其基础,只针对查询流程讲解剖析。

本片博客阐述的过程为

1、上一个标识过的sql语句,展示查询执行的流程

2、上一个流程图

3、做一个例子逐步深入分析,帮助理解

4、做一个装逼的总结

sql查询语句的处理步骤,流程图

金沙棋牌app手机下载 1

 

1.1 功能特性

SQLite是一款轻型的嵌入式数据库。在嵌入式设备中,可能只需要几百K的内存就够了。它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快。
SQLite属于关系型数据库。

常用关系型数据库:

PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase
嵌入式移动客户端:SQLite
这种数据库存储数据是以表(table)为基本单位的。

sql查询语句的处理步骤,代码清单

 

--查询组合字段
select (6)distinct (8)top(<top_specification>)(5)<select_list>
--连表
(1)from (1-J)<left_table><join_type> join <right_table> on <on_predicate>
        (1-A)<left_table><apply_type> apply <right_table_expression> as <alias>
        (1-P)<left_table> pivot (<pivot_specification>) as <alias>
        (1-U)<left_table> unpivot (<unpivot_specification>) as <alias>
--查询条件
(2)where <where_pridicate>
--分组
(3)group by <group_by_specification>
--分组条件
(4)having<having_predicate>
--排序
(7)order by<order_by_list>

 

说明:

1、顺序为有1-8,8个大步骤,1-J,1-A,1-P,1-U,为并行次序。如果不够明白,接下来我在来个流程图看看。

2、执行过程中也会相应的产生多个虚拟表(下面会有提到),以配合最终的正确查询。

实例准备,创建表,插入数据,写要分析的实例查询语句

1、首先创建2各表

金沙棋牌app手机下载 2

2、创建两个表,并插入表数据,脚本如下 

金沙棋牌app手机下载 3金沙棋牌app手机下载 4

USE [test]
GO
/****** Object:  Table [dbo].[Member]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Member](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](30) NULL,
    [phone] [varchar](15) NULL,
 CONSTRAINT [PK_MEMBER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Order]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Order](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [member_id] [int] NULL,
    [status] [int] NULL,
    [createTime] [datetime] NULL,
 CONSTRAINT [PK_ORDER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET IDENTITY_INSERT [dbo].[Member] ON 

GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (1, N'张龙豪', N'18501733702')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (2, N'Jim', N'15039512688')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (3, N'Tom', N'15139512854')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (4, N'Lulu', N'15687425583')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (5, N'Jick', N'13528567445')
GO
SET IDENTITY_INSERT [dbo].[Member] OFF
GO
SET IDENTITY_INSERT [dbo].[Order] ON 

GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (1, 1, 3, CAST(0x0000A40900B3BBFB AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (2, 2, 1, CAST(0x0000A40900B3CEF2 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (3, 3, 4, CAST(0x0000A40900B3D2D0 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (4, 4, 0, CAST(0x0000A40900B3D660 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (5, 5, 1, CAST(0x0000A40900B3D9B9 AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (6, 6, 2, CAST(0x0000A40900B3DFEA AS DateTime))
GO
INSERT [dbo].[Order] ([id], [member_id], [status], [createTime]) VALUES (7, NULL, 0, CAST(0x0000A40900E34971 AS DateTime))
GO
SET IDENTITY_INSERT [dbo].[Order] OFF
GO
ALTER TABLE [dbo].[Order] ADD  DEFAULT (getdate()) FOR [createTime]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'姓名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'Name'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'电话' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member', @level2type=N'COLUMN',@level2name=N'phone'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'会员表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Member'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'会员编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'member_id'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单状态' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'status'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'下单日期' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order', @level2type=N'COLUMN',@level2name=N'createTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'订单表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Order'
GO

View Code 

3、编写咱们要解析的查询语句,即本篇要查询的实例语句。

select top(4)  status , max(m.id) as maxMemberID
from [dbo].[Member] as m right outer join [dbo].[Order] as o 
on m.id=o.member_id 
where m.id>0
group by status 
having status>=0
order by maxMemberID asc

1.2 参考资料

1.博客链接:链接
2.具体到每一个操作方法的博客:链接
3.使用C操作SQLite的博客:链接
4.sqlite_master介绍:链接

sql查询语句的处理步骤,流程图

金沙棋牌app手机下载 5

 注:上述流程图保留原作。经过实验和查阅资料,做如下修改:计算表达式为第5步,distinct为第6步,order by为第7步,top为第8步,应在order by之后

实例语句分步骤分析

第一步,从from开始。

1.1、加载左表

from [dbo].[Member] as m 

查询结果:member表中的所有数据

1.2、这里应该是 right outer join ,但是这里在sql中被定义分解为2个步骤,即join ,right outer join 。表达式关键字从左到右,依次执行。

join [dbo].[Order] as o 

查询结果:存入虚拟表vt1,为两个表的笛卡尔集合。这里你或许不明白什么叫笛卡尔集合,我打个比方给说说,还望不要嫌弃,就是小朋友握手问题,A班里有3个学生(看作一个表的三条数据),B班里有2个学生(看作另外一个表的2条数据).B班小朋友跟A班小朋友搞联欢晚会,首先要每个人都要确保跟另外一个班的同学我一下手,那么交叉出来的集合就是(2*3=6)有6条不同的轨迹。这个轨迹的集合就是笛卡尔集合。如果你还不明白,我再说下,就是m(5条数据)表中的第一条数据跟o(7条数据)表中的所有数据握下手,有7条,然后依次类推共有35条不同的数据。这里的null值也是要加进来的。

1.3、on 筛选器

on m.id=o.member_id 

查询结果:金沙棋牌app手机下载 6从上一步的笛卡尔集合35条数据中删除掉不匹配的行,就得到啦5条数据,存入虚拟表Vt2

1.4、添加外部行(outer row)

right outer join [dbo].[Order] as o 

查询结果为:金沙棋牌app手机下载 7右表(order)作为保留表,把剩余的数据重新添加到上一步的虚拟表中vt2,生成虚拟表vt3.

第二部,进入where阶段

where m.id>0

查询结果:存入虚拟表vt4,为筛选的条件为true的结果集,这里加入一个记忆点,就是,where的筛选删除为永久的,而on的筛选删除为暂时的,因为on筛选过后,有可能会经过outer添加外部行,重新把数据加载回来,而where则不能。

第三部,group by分组

group by status

查询结果:存入vt5,以status列的数值开始分组,即status列,值一样的分为一组,这里的两个null在三值逻辑中被视为true。三值逻辑:true,false,null。此三值,null为未知,是数据的逻辑特色,有的地方两个null相等为ture,在有些地方则为false。这个你百度下看看有很多讲解。

 第四步,having筛选器

having status>=0 

查询结果:筛选分好组的组数据,把不满足条件的删除掉

第五步,select查询挑拣计算列

5.1、计算表达式

select status , max(m.id)

查询结果:从分过组的数据中计算各个组中的最大m.id,列出要筛选显示的列。

5.2、distinct过滤重复

5.3、top 结合order by 筛选 多少行,但这里的数据没有排序只是把多少行数据列出来而已。

第六部,order by 排序显示。

2 移植

实例准备,创建表,插入数据,写要分析的实例查询语句

1、首先创建两个表

金沙棋牌app手机下载 8

2、创建两个表,并插入表数据,脚本如下 

金沙棋牌app手机下载 9金沙棋牌app手机下载 10

USE [test]
GO
/****** Object:  Table [dbo].[Member]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Member](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](30) NULL,
    [phone] [varchar](15) NULL,
 CONSTRAINT [PK_MEMBER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[Order]    Script Date: 2014/12/22 14:05:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Order](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [member_id] [int] NULL,
    [status] [int] NULL,
    [createTime] [datetime] NULL,
 CONSTRAINT [PK_ORDER] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET IDENTITY_INSERT [dbo].[Member] ON 

GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (1, N'张龙豪', N'18501733702')
GO
INSERT [dbo].[Member] ([id], [Name], [phone]) VALUES (2, N'Jim', N'15039512688')
GO
INSERT [dbo].[Member] ([id

蛋疼的总结,装逼是有依据的

本篇博客参考:《Microsoft SQL Server 2008技术内幕:T-SQL查询》,感谢阅读,(C#).NET技术分享QQ群: 232458226,欢迎加入。

 

2.1 下载源码

sqlite的官方网址为:链接
sqlite下载网址为:链接

我下载的源码如下所示:

金沙棋牌app手机下载 11

源码下载

完成解压:

$ tar xzf sqlite-autoconf-3200000.tar.gz

2.2 编译安装

2.2.1 安装到本机

可以执行如下命令:

$ cd sqlite-autoconf-3200000/
$ ./configure --prefix=/home/wityuan/Downloads/sqlite-autoconf-3200000/temp CC=gcc
$ make
$ sudo make install

之后,安装成功,到temp目录下,查看文件:

金沙棋牌app手机下载 12

安装成功

金沙棋牌app手机下载 13

运行sqlite命令

2.2.2 安装到树莓派A20上

这种交叉编译与安装到PC上步骤是差不多的。

$ make clean
$ cd sqlite-autoconf-3200000/
$ ./configure --prefix=/home/wityuan/Downloads/sqlite-autoconf-3200000/temp_A20 --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld
$ make
$ sudo make install

将生成的temp_A20目录下的文件内容对应拷贝到/usr/lib和/usr/include目录下。

需要注意,前面做了PC端的编译,如果不make clean,那么后面make的时候,使用的还是以前的make的结果。

最终我们生成了如下内容:

金沙棋牌app手机下载 14

生成sqlite相关文件

如果在A20上运行不起来,我们首先要看sqlite3的文件格式,如下图所示的错误格式:

金沙棋牌app手机下载 15

错误格式

金沙棋牌app手机下载 16

正确格式

下面可以验证:
先将 bin目录下的sqlite3移到A20的bin目录下,然后执行sqlite3。

root@marsboard:~# chmod +x sqlite3
root@marsboard:~# cp sqlite3 /bin/
root@marsboard:~# sqlite3
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
sqlite>

可以发现,已经运行起来了。

下面还有一个比较重要的步骤:

上面只是在A20板子上能运行应用程序,但是在写程序编码的时候,我们还是需要包含一些库等等,才能让PC机去执行这个过程,所以,需要将交叉编译过后的lib,include等文件拷贝到PC机上的交叉编译的工具的相应目录下。

先看PC机上的交叉编译目录位置:

金沙棋牌app手机下载 17

PC机交叉编译工具位置

我使用的是arm-linux-gnueabihf工具链。所以我需要操作的内容如下:

wityuan@ubuntu:~/Downloads/sqlite-autoconf-3200000/temp_A20$ sudo cp include/* /usr/arm-linux-gnueabihf/include/
wityuan@ubuntu:~/Downloads/sqlite-autoconf-3200000/temp_A20$ sudo cp lib/* /usr/arm-linux-gnueabihf/lib/
cp: omitting directory `lib/pkgconfig'
wityuan@ubuntu:~/Downloads/sqlite-autoconf-3200000/temp_A20$ 

金沙棋牌app手机下载 18

拷贝库和头文件

3 使用SQLite数据库

3.1 基本操作思想

数据库存储数据的步骤:
1)新建一张表(table)
2)添加多个字段(column,列,属性)
3)添加多行记录(row.record,每行存放多个字段对应的值)

3.2 基本操作方法

3.2.1 数据库操作方法分类

1.数据定义语句(DDL:Data Definition Language)
包括create和drop等操作,在数据库中创建新表或删除表(create table或 drop table)。

2.数据操作语句(DML:Data Manipulation Language)
包括insert、update、delete等操作,也就是添加、修改、删除表中的数据。

3.数据查询语句(DQL:Data Query Language)
可以用于查询获得表中的数据,select是用得比较多的语句,还有一些常用的语句,例如:where,order by,group by和having。

3.2.2 开始操作

1.创建数据库

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .schema
sqlite> 

通过该命令,就能生成一个数据库test.db

2.创建表

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> CREATE TABLE stutable(sid,sname,sage)
   ...> ;
sqlite> .schema
CREATE TABLE stutable(sid,sname,sage);
sqlite> 
sqlite> 

这里就可以创建出表stutable。

3.插入数据

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE stutable(sid,sname,sage);
sqlite> insert into stutable(sid,sname,sage) values(1,"jack","23")
   ...> ;
sqlite> insert into stutable(sid,sname,sage) values(2,"rose","21");
sqlite> 

这里表示插入两条信息,1,jack,23与2,rose,21两条。

4.查询数据

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> select * from stutable
   ...> ;
1|jack|23
2|rose|21
sqlite> 

这里表示的就是查询到的上面插入的2条数据。

5.修改数据

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> update stutable set sname="answer" where sid=1 ;
sqlite> select * from stutable
   ...> ;
1|answer|23
2|rose|21
sqlite> 

6.一些命令行方式小技巧
1)头部分隔

sqlite> .header on
sqlite> select * from stutable;
sid         sname       sage      
----------  ----------  ----------
1           answer      23        
2           rose        21        
sqlite> 

7.删除表内容

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> 
sqlite> select * from stutable
   ...> ;
1|answer|23
2|rose|21
sqlite> delete from stutable;
sqlite> select * from stutable;
sqlite> 

可以看到最后查询表的内容时候,已经不存在了。

8.删除其中一项内容

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .table
stutable
sqlite> select * from stutable
   ...> ;
1|john|23
2|rose|22
sqlite> 
sqlite> delete from stutable where sid=1;
sqlite> select * from stutable;
2|rose|22
sqlite> 

9.删除表

wityuan@ubuntu:~/Desktop$ sudo sqlite3 test.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .table
stutable
sqlite> drop table stutable;
sqlite> .table
sqlite> 

可以看到,最后使用.table后,stutable表已经不存在了。

4 使用C语言来操作SQLite

4.1 创建数据库

建立create_database.c文件,代码内容如下:

#include <stdio.h>
#include "sqlite3.h"

int main(int argc,char *argv[])
{
  int ret;
  sqlite3 *db = 0;
  ret = sqlite3_open("./sqlite3-demo.db",&db);
  if(ret != SQLITE_OK){
    fprintf(stderr,"Cannot open db: %sn",sqlite3_errmsg(db));
    return 1;
  }
  printf("Open databasen");
  return 0;
}

由于我是使用的官方源码编译到ubuntu中的,所以要注意将lib和include文件拷贝到系统的目录中,如下所示:

$ sudo cp include/* /usr/include/
$ sudo cp lib/* /usr/lib/ 
cp: omitting directory `lib/pkgconfig'

然后编译,运行:

$ gcc create_database.c -o create_database -lsqlite3
$ ./create_database 
Open database
$  ls 
create_database  create_database.c  sqlite3-demo.db

可以看到,创建数据库sqlite3-demo.db成功。

4.2 创建表

新建一个c文件,命名为create_table.c,内容如下:

#include <stdio.h>
#include "sqlite3.h"

int main(int argc,char *argv[])
{
  int ret;
  sqlite3 *db = 0;
  char *ErrMsg;
  char *sql_create_table = "create table stutable(sid,sname,sage);";
  ret = sqlite3_open("./sqlite3-demo.db",&db);
  if(ret != SQLITE_OK){
    fprintf(stderr,"Cannot open db: %sn",sqlite3_errmsg(db));
    return 1;
  }
  printf("Open databasen");

  ret = sqlite3_exec(db,sql_create_table,0,0,&ErrMsg);
  if(ret != SQLITE_OK)
  {
    fprintf(stderr,"SQL Error:%sn",ErrMsg);
    sqlite3_free(ErrMsg);
  }

  return 0;
}

然后,编译执行:

wityuan@ubuntu:~/Desktop/sqlite$ gcc create_table.c -o create_table -lsqlite3
wityuan@ubuntu:~/Desktop/sqlite$ sqlite3 sqlite3-demo.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .table
sqlite> .exit
wityuan@ubuntu:~/Desktop/sqlite$ ./create_table 
Open database
wityuan@ubuntu:~/Desktop/sqlite$ 
wityuan@ubuntu:~/Desktop/sqlite$ sqlite3 sqlite3-demo.db
SQLite version 3.20.0 2017-08-01 13:24:15
Enter ".help" for usage hints.
sqlite> .table
stutable
sqlite> .exit
wityuan@ubuntu:~/Desktop/sqlite$ 

可以看到,成功的创建表stutable。

再来看这么一个问题,也就是上面的这个程序执行两次,就会发现程序会报错:

金沙棋牌app手机下载 19

创建数据库报错

显然,解决思路是判断表存在与否,如果不存在,我们就创建,否则就不再创建了。

写到这里,就需要知道sqlite3本身也会维护另外一张表,表名称为sqlite3_master;其存储了我们建立的表的信息,如:表名称,创建的sql语句等。如下命令所示:

sqlite> select * from sqlite_master;
type|name|tbl_name|rootpage|sql
table|stutable|stutable|2|CREATE TABLE stutable(sid,sname,sage)
sqlite> 

可以看到sqlite_master,该表创建的字段有type,name,tbl_name,rootpage,sql。

所以在程序里面,解决起来,也很简单,直接查询sqlite_master中含有stutable记录的数量,如果为0,就说明没有创建该表,就可以执行创建操作。否则,就不用创建了。

使用的语句为:

select count(*) from sqlite_master where type='table' and name ='stutable';  

修改上面的代码,使用如下代码:

#include "sqlite3.h"
#include "stdio.h"
#include "stdlib.h"
int table_exist = 0;
static int callback(void *NotUsed,int argc,char **argv,char **azColName){
  int i;
  printf("argc:%drn",argc);
  for(i = 0 ;i < argc; i ++){
    printf("%s = %sn", azColName[i],argv[i]?argv[i]:"NULL");
  }
  table_exist = atoi(argv[0]);
  printf("table_exist:%drn",table_exist);
  printf("n");
  return 0;
}
int main(int argc,char *argv[])
{
  int ret;
  sqlite3 *db = 0;
  char *ErrMsg;
  char *sql_create_table = "create table stutable(sid,sname,sage);";
  char *sql_table_exits = "select count(*) from sqlite_master where type='table' and name ='stutable'";
  ret = sqlite3_open("./sqlite3-demo.db",&db);
  if(ret != SQLITE_OK){
    fprintf(stderr,"Cannot open db: %sn",sqlite3_errmsg(db));
    return 1;
  }
  printf("Open databasen");
  ret = sqlite3_exec(db,sql_table_exits,callback,0,&ErrMsg);
  if(ret == SQLITE_OK)
  {
    if(table_exist == 0)
    {
      ret = sqlite3_exec(db,sql_create_table,0,0,&ErrMsg);

      if(ret != SQLITE_OK)
      {
        fprintf(stderr,"SQL Error:%sn",ErrMsg);
        sqlite3_free(ErrMsg);
      }
      printf("---create table----rn");
    }
    else
    {
      printf("--table exists---rn");
    }
  }
  else
  {
    fprintf(stderr,"SQL Error:%sn",ErrMsg);
  }
  return 0;
}

我再列出执行结果:

wityuan@ubuntu:~/Desktop/sqlite$ ./create_table
Open database
argc:1
count(*) = 0
table_exist:0

---create table----
wityuan@ubuntu:~/Desktop/sqlite$ ./create_table
Open database
argc:1
count(*) = 1
table_exist:1

--table exists---
wityuan@ubuntu:~/Desktop/sqlite$ 

可如同所示:

金沙棋牌app手机下载 20

sqlite创建表

4.3 插入数据

该操作也是需要判断是否已经存在该条目,如果有,则使用update更新数据,否则就执行insert操作。
该操作也是使用count(*),思想与上面的一样,所以也就不再往下面说了。

本文由金沙棋牌发布于金沙棋牌app手机下载,转载请注明出处:语句查询执行顺序,sql语句查询执行顺序金沙棋

关键词: