童话故事 — 蓝牙通信 — 连接手机和嵌入式设备

一、排序检索数据

1.排序数据SELECT prod_name
FROM Products ORDER BY prod_name(对prod_name列以字母顺序排序数据)

ORDER
BY子句的岗位

在指定一条ORDER
BY子句时,应该保证它是SELECT语句中最终一条子句。假如它不是最终的子句,将会油但是生谬误音信。
经过非采用列举行排序
普普通通,ORDER
BY子句中运用的列将是为体现而拔取的列。不过,实际上并不一定要这么,用非检索的列排序数据是一心合法的。

2.按四个列排序SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
prod_price,prod_name

图片 1

最首要的是领略在按四个列排序时,排序的一一完全按规定举办。换句话说,对于上述例子中的输出,仅在六个行有所同样的prod_price值时才对成品按prod_name举行排序。如若prod_price列中具备的值都是绝无仅有的,则不会按prod_name排序。

3.按列地点排序SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
2,3 那么些和按三个列排序结果是同等的,无非就是理所当然的列名称改成了岗位序号。

图片 2

能够看出,这里的出口与地点的询问同一,不同之处在于ORDER
BY子句。SELECT清单中指定的是挑选列的周旋地方而不是列名。ORDER BY
2代表按SELECT清单中的第二个列prod_name举办排序。ORDER BY
2,3代表先按prod_price,再按prod_name举办排序。
这一技巧的严重性利益在于不要再行输入列名。但它也有缺点。首先,不明朗给出列名有可能引致错用列名排序。其次,在对SELECT清单举行改动时容易错误地对数码举行排序(忘记对ORDER
BY子句做相应的更改)。最终,假若进展排序的列不在SELECT清单中,显然无法使用这项技艺。

4.指定排序方向SELECT
prod_id,prod_price,prod_name FROM Products ORDER BY
prod_price DESC

SELECT prod_id,prod_price,prod_name FROM
Products ORDER BY prod_price DESC,prod_name

图片 3

DESC关键字只使用到间接放在其眼前的列名。在上例中,只对prod_price列指定DESC,对prod_name列不点名。由此,prod_price列以降序排序,而prod_name列(在各种价位内)依旧按正统的升序排序。

警示:在六个列上降序排序
如若想在五个列上举行降序排序,必须对每一列指定DESC关键字。
请留心,DESC是DESCENDING的缩写,这两个重大字都可以采用。与DESC绝对的是ASC(或ASCENDING),在升序排序时得以指定它。但实则,ASC没有多大用处,因为升序是默认的(假设既不点名ASC也不指定DESC,则只要为ASC)。
提醒:区分轻重缓急写和排序依次
在对文本性数据开展排序时,A与a相同呢?a位于B在此以前,如故Z之后?这么些问题不是辩论问题,其答案取决于数据库的装置方法。
在字典(dictionary)排序依次中,A被视为与a相同,这是大多数数据库管理类此外默认行为。不过,许多DBMS允许数据库管理员在需要时改变那种作为(假设您的数据库包含大量外文字符,可能必须这样做)。
此处的关键问题是,倘诺的确需要变更这种排序依次,用简短的ORDER
BY子句可能做不到。你必须请求数据库管理员的赞助。

 

二、过滤数据

1.where语句SELECT
prod_name,prod_price FROM Products WHERE
prod_price=3.49

警戒:WHERE子句的职位
在同时采取ORDER BY和WHERE子句时,应该让ORDER
BY位于WHERE其后,否则将会暴发错误。例如:SELECT prod_name,prod_price FROM
Products WHERE prod_price=3.49 ORDER BY prod_name
ASC

图片 4

 

2.反省单个值:SELECT
prod_name,prod_price FROM Products WHERE prod_price < 0

3.不般配检查:SELECT
vend_id,prod_name FROM Products WHERE vend_id <>’DLL01′

4.范围值检查:SELECT
prod_name,prod_price FROM Products WHERE prod_price BETWEEN 5 AND
10

5.空值检查: SELECT cust_name
FROM customers WHERE cust_email IS NULL

高飞狗:

三、高级数据过滤

1.AND操作符SELECT
prod_id,prod_price,prod_name FROM Products WHERE
vend_id=’DLL01′ AND prod_price <=4

此SQL语句检索由供应商DLL01成立且价格小于等于4美元的具备产品的名称和价格。这条SELECT语句中的WHERE子句包含五个标准化,用AND关键字联结在联合。AND提醒DBMS只回去满足所有给定条件的行。假若某个产品由供应商DLL01创造,但价格高于4英镑,则不检索它。

AND
用在WHERE子句中的关键字,用来提示检索满意所有给定条件的行。
本条例子只含有一个AND子句,由此最多有七个过滤条件。能够扩张四个过滤条件,每个条件间都要运用AND关键字。
说明:没有ORDER BY子句
为了节省空间,也为了削减你的输入,我在众多事例里大概了ORDER
BY子句。因而,你的输出完全有可能与书上的出口不平等。尽管再次回到行的多少连续对的,但它们的依次可能两样。当然,假使你愿意也足以增长一个ORDER
BY子句,它应当置身WHERE子句之后。
2.OR操作符SELECT
vend_id,prod_price,prod_name FROM Products WHERE
vend_id=’DLL01′ OR
vend_id=’BRS01′

此SQL语句检索由任一个指定供应商创设的装有产品的产品名和价格。OR操作符告诉DBMS匹配任一条件而不是还要匹配五个尺码。 

图片 5

3.求值挨家挨户(AND
OR)

输入:

SELECT
prod_name, prod_price FROM Products 

WHERE
vend_id = ‘DLL01’ OR vend_id = ‘BRS01’ AND prod_price >=
10

输出:

图片 6

题目:请看上边的结果。重返的行中有**4行价格低于10**新币,显然,重临的行未按预期的展开过滤。为啥会这么呢?缘由在于求值的次第。SQL(像多数语言同样)在拍卖OR操作符前,优先处理AND操作符。当SQL看到上述WHERE子句时,它了解为:由供应商BRS01创造的价钱为10加元以上的保有产品,以及由供应商DLL01创设的所有成品,而不管其标价怎么。换句话说,由于AND在求值过程中先行级更高,操作符被张冠李戴地结合了。

缓解形式:

SELECT prod_name, prod_price FROM Products 

WHERE (vend_id =
‘DLL01’ OR vend_id = ‘BRS01’) AND
prod_price >= 10

实际上如果用括号括起来就好了

提拔:在WHERE子句中动用圆括号
另外时候利用所有AND和OR操作符的WHERE子句,都应有运用圆括号明确地分组操作符。不要过分倚重默认求值顺序,尽管它实在如你期望的那么。使用圆括号没有什么样坏处,它能祛除歧义。

4.IN操作符

输入:

SELECT
vend_id,prod_name,prod_price FROM Products
WHERE
vend_id IN (‘DLL01′,’BRS01’)
ORDER
BY prod_name

输出:

图片 7

为什么要接纳IN操作符?其优点为:

  • 在有广大官方选项时,IN操作符的语法更了然,更直观。
  • 在与另外AND和OR操作符组合使用IN时,求值顺序更易于管理。
  • IN操作符一般比一组OR操作符执行得更快(在上头这一个合法选项很少的事例中,你看不出性能差距)。
  • IN的最大亮点是可以蕴涵其他SELECT语句,可以更动态地建立WHERE子句。第11课会对此举办详尽介绍。

IN
WHERE子句中用来指定要匹配值的清单的机要字,功效与OR相当。

5.NOT操作符

SELECT
prod_name FROM Products
WHERE NOT
vend_id = ‘DLL01’
ORDER
BY prod_name;

为什么使用NOT?对于这里的这种简单的WHERE子句,使用NOT确实尚未什么优势。但在更扑朔迷离的子句中,NOT是可怜有效的。例如,在与IN操作符联合使用时,NOT可以万分简单地找出与规则列表不匹配的行。

作者:今孝
出处:http://www.cnblogs.com/jinxiao-pu/p/6814043.html
本文版权归作者和网易共有,欢迎转载,但未经作者同意必须保留此段注明,且在小说页面显明地点给出原文连接。

认为好就点个推荐把!

“平时的想,现在的你…”

布鲁托:

“哈罗!高飞!心思不错嘛!”

高飞狗:

“嗨!又遭逢难题了,百思不得其解,头昏目眩的,心思糟透了!”

布鲁托:

“又在商量怎么高科技项目?”

高飞狗:

“根本算不上什么高科技,我有一个PM2.5监测装置,就是可以测量与记录环境温度、湿度和颗粒物浓度的东东,受应用条件的限量,没有安排显示屏,为了可以在现场对其举办配备、管理并赢得测量数据,想在这些设置上总是一个蓝牙模块,然后借援手机通过蓝牙通信实现那么些效用。”

布鲁托:

“蓝牙通信是很干练的技巧,应该容易解决。”

高飞狗:

“在妹夫大上本来很容易就招来到自身的蓝牙模块并打响开展了杂交,不过接下去咋样支付一个App与PM2.5监测装置通信,我是一头雾水啊!”

布鲁托:

“开发手机App,用Android Studio就可以。”

高飞狗:

“Android Studio开发出来的App无法在iOS上运行。再说,我只会C++语言,而Android Studio要用java语言开发。”

布鲁托:

“我们不妨去找找黛丝大学生,听听他有什么高见。”

高飞狗:

“又去找她? 挺不佳意思的。”

布鲁托:

“黛丝硕士是个好心人,乐于助人,上次我们去呼救,她一些气派都并未,而且他对您的态度极为好转,难道你没瞧出来? 没准人家每一日盼着您去问问题吧!”

高飞狗:

“真的吗?你看出来转机来了?我还有机会?”

布鲁托:

“我们这就走吗!”

高飞狗和布鲁托再度到来黛丝家并按下了门铃,”叮铃铃…叮铃铃…”。

黛丝:

“谁啊? 啊哦!是你们两位,快请进!”

“快请坐,喝点咖啡或者乌龙茶?”

高飞狗:

“不用这么客气。黛丝,前天来又得辛勤你。”

黛丝:

“是何许事啊?”

高飞狗:

“我想用C++开发一个手机App,通过蓝牙通信管理我的PM2.5监测装置,而且那些App必须在Android和iOS上都能运作。”

黛丝:

“这有哪些难的哎。”

高飞狗:

“我不怕不知该怎么动手,一点思路都尚未。”

黛丝:

“最近恰好做了一个接近的门类,正好跟你们说说,对本身的话也算温习所学知识吧。”

布鲁托:

“您太谦虚了!”

黛丝:

“咱们先说蓝牙通信的法则,然后再说具体落实啊。”

“蓝牙通信和TCP/UDP的原理基本相同,几乎如出一辙。参见下表。”

 

通信特征

TCP/UDP通信

蓝牙通信

通信模式

客户端-服务器模式

客户端-服务器模式

通信端点

TCP端口

服务

通信端点标识方法

TCP端口号,是16位二进制数

服务UUID,是128位二进制数

客户端通信过程

创建客户端Socket

连接服务器

发送数据

接收数据

创建客户端Socket

连接服务器

发送数据

接收数据

 

黛丝:

"看见了吧,与TCP/UDP相比,区别仅仅在于,蓝牙用服务代替端口,用服务UUID代替端口号,且服务UUID较长。"

"用手机App管理嵌入式设备,手机就是客户端,嵌入式设备上的蓝牙模块就是服务器。"

高飞狗:

"真的是一目了然!"

黛丝:

"TCP/UDP标准定义了一组固定的端口对应一组标准化服务。例如,TCP端口80用于Web服务;TCP端口21用于FTP服务。"

"类似地,蓝牙标准也定义了一组固定的服务UUID对应一组标准化服务。"参见下表:

 

蓝牙服务名称

服务UUID

Serial Port

00001101-0000-1000-8000-00805F9B34FB

LAN Access Using PPP

00001102-0000-1000-8000-00805F9B34FB

DialupNetworking

00001103-0000-1000-8000-00805F9B34FB

OBEXObjectPush

00001105-0000-1000-8000-00805F9B34FB

OBEXFileTransfer

00001106-0000-1000-8000-00805F9B34FB

Cordless Telephony

00001109-0000-1000-8000-00805F9B34FB

Audio Source

0000110A-0000-1000-8000-00805F9B34FB

 

黛丝:

"由于蓝牙服务UUID太长,就用16进制数表达,遵循8-4-4-4-12的方法表示。"

"蓝牙通信与TCP/UDP通信的关键不同在于,蓝牙服务器都有一个SDP服务,也就是服务发现服务,供客户端查询蓝牙服务器能够提供哪些服务。"

"通常,用于嵌入式设备的蓝牙模块都提供Serial Port服务,简称SPP,然后提供一个UART连接嵌入式设备",如下图所示。

 

图片 8

黛丝:

"由此,手机App与嵌入式设备通信的基本流程如下(假设蓝牙模块已经与手机配对完毕):

步骤1:选择要进行通信的蓝牙模块

步骤2:查询蓝牙模块的服务。通常已配对的蓝牙设备的服务列表已缓存在手机里。

步骤3:如果存在SPP服务,恭喜你!

步骤4:用SPP服务UUID创建一个客户端Socket。

步骤5:用客户端Socket连接蓝牙模块。

步骤6:调用客户端Socket的SendData()发送数据给蓝牙模块,蓝牙模块会将收到的数据通过UART转发给嵌入式设备。

步骤7:如果嵌入式设备发送数据给蓝牙模块,蓝牙模块会转发给手机,手机会缓存这些数据,App可调用客户端Socket的ReceiveData()接收数据。"

黛丝:

"蓝牙通信的原理就是这样的。"

高飞狗:

"黛丝,你讲得太明白了,今晚我一定要好好请请你、亲亲你!

黛丝:

"你就知道邪思歪想!"

高飞狗:

"那具体如何实现呢?"

黛丝:

"具体实现方法也很简单。我们只要选择Rad Studio作为开发工具,用C++编写一套源代码就可以生成适用于Android和iOS上运行的App,是不是很酷?"

"有关Rad Studio就不在此累述,GUI界面的设计也很简单,我们聚焦如何通过蓝牙进行数据收发。"

 

借助蓝牙SPP服务,实现手机与嵌入式设备之间的通信

注1:本文旨在明晰蓝牙通信原理,仅列出扼要代码,如需完整代码,可联系本人。

注2:确保已开启手机蓝牙

注3:确保蓝牙模块已在手机的已配对设备列表中。

// 取得并保存蓝牙管理器对象

TBluetoothManager *BtManager = TBluetoothManager::Current;

 

// 取得并保存蓝牙适配器对象

BtAdapter = BtManager ->CurrentAdapter;

 

// 取得已配对的蓝牙设备列表

TBluetoothDeviceList *PairedDevices = BtManager ->GetPairedDevices();

 

// 将蓝牙设备列表显示在组合框cbPairedDevices中(代码略)

 

// 获取组合框中被选中的蓝牙设备对象

TBluetoothDevice * SelDevice = PairedDevices ->Items[cbPairedDevices->ItemIndex];

 

// 获取该蓝牙设备的服务列表

TBluetoothServiceList * ListServices = SelDevice->GetServices();

 

// 在服务列表中查询是否支持SPP服务(代码略)

 

// 若支持SPP服务

 

// 用SPP服务UUID创建一个客户端Socket。

TBluetoothSocket *BtSocket = SelDevice ->CreateClientSocket(StringToGUID(SPP_GUI), false);

 

// 用客户端Socket连接蓝牙模块。

BtSocket ->Connect();

 

// 调用客户端Socket的SendData()发送数据给蓝牙模块,蓝牙模块会将收到的数据通过UART转发给嵌入式设备。

BtSocket ->SendData(DataArray); // DataArray是一个数组

 

// 如果嵌入式设备发送数据给蓝牙模块,蓝牙模块会转发给手机,手机会缓存这些数据,App可调用客户端Socket的ReceiveData()接收数据。"

BtSocket->ReceiveData(50); // 接收数据,限时等待50ms

 

黛丝:

"以上就是手机App与蓝牙模块间收发数据的基本流程及其实现。"

高飞狗:

"黛丝,你讲得太深入浅出了!啊哦,快到饭点了,我请你吃个便饭,聊表谢意!"

黛丝:

"已经有人约我吃饭了,你们就赶紧回去试验,有什么问题随时Call我。"

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注