【原创】6. 在MYSQL++中实现SQL语法中的NULL
这次要说明的是在MYSQL++中为了实现SQL中的NULL而做出的一系列的举措。我的感觉是Null<T, B>类型通常出现在SSQLS和template Query中比较多。
1. 什么是SQL语法中的NULL(以后简称SQL NULL,区别于C++ NULL)
我们可以像下面这样创建一张表
CREATE TABLE tbl1 (
id INT NOT NULL,
name CHAR(20) ,
time TIMESTAMP NULL );
在MYSQL中,上述语句的创建出来的表的列的情况是(dbvisualize的截图),
也就是说,如果我们不指定NOT NULL,默认的就是NULL。
再来看一下插入数据
insert into tbl1(id, time) values( 2, NOW() );
这里没有指定可以为NULL的name的值,那么结果是怎样的?
那么是否可以通过一句update语句来重置上面漏掉的、已经为NULL的name?完全可以。update tbl1 set name = ‘hello world’ where id = 2;
也就是说,SQL中的NULL并不是我们通常看到的字符串“”,而是一种状态,表示“空”。
MYSQL++文档里说是,SQL null is equal to nothing else. SQL null exists when every value for a particular column is legal and you need something that means "no legal value".)。
最后提一句,如果我们希望显式地往数据库中插入一个null,那么应该使用语句
insert into tbl1(id, name, time) values( 2, null, NOW() );
2. MYSQL++中模拟SQL NULL的类型
在MYSQL++中模拟SQL NULL的只有两个文件,分别是null.h和null.cpp。
- null.cpp
其中在null.cpp中只定义了如下一行代码
const std::string null_str("NULL");
- null.h
在null.h中主要定了两个主类型(分别是null_type和Null<type, Bahavior>)以及三个工具类型(NullIsNull, NullIsZero, NullIsBlank)1. null_type这个类型无比简单
确实!什么都没有,除了一个让编译器为隐式类型转换报错的protected方法。也就是说,如下的代码是不被认可的。
// 说明:
// 1. mysqlpp::Null<T, Bahavior=NullIsNull> 的确是有一个构造函数只接受一个null_type的
// 2. mysqlpp:::null 在null.h中被定义成一个const null_type null = null_type(); int foo = return_some_value_for_foo();
mysqlpp::Null<int> bar = foo ? foo : mysqlpp::null;
在上述例子中,如果foo == 0,那么编译器就会执行foo = mysqlpp::null,也就是执行了protected方法mysqlpp::null.operator int(),所以编译器就报错了(因为引用了一个protected方法)另外,在null.h中,还定义了一个mysqlpp::null,我估计这个定义完全就是为了让客户端代码不经意间就用上了mysqlpp::null,例如,Null<int> foo = null;这里的null将会被编译器理解为mysqlpp::null。
2. 三个工具类型
这三个工具类型提供了类似的方法,不多说了,比较好理解。他们将会成为表示可以供Null的column的数据类型的对于NULL的解释的任务。
3. Null<Type, Bahavior = NullIsNull>类型该类型是表示一个可以为SQL NULL的column的数据的数据类型。其实它的含义就是“可以保存真实数据或者SQL NULL”的数据结构。例如对于有如下的表格
CREATE TABLE tbl1 (
id INT NOT NULL,
name CHAR(20) ,
num SMALLINT NULL );
对于name列,就可以在C++代码中使用Null<sql_char>表示,对于num列,就可以用Null<sql_smallint>表示。说明(取自sql_types.h)
typedef int16_t sql_smallint;
typedef std::string sql_char;
MYSQL++的作者一再强调,Null<T,B>类型是一个“holds data that can be null”的类型,也就是说,他真正模仿了SQL NULL。例如,对于上述的name列,我们可以对他赋值为null,也可以赋值为某个字符串。同样,这里的Null<T, B>类型就可以有这个功能,
It can hold a non-null value, you can then assign null to it (using MySQL++'s global mysqlpp::null object), and then assign a regular value to it again
- 成员变量
该类型其实只有两个成员变量,
1. Type data;
这里的Type就是Null<T, B>中的T,例如如果是Null<sql_char>,那么这个Type就是sql_char。它表示的是如果该列非Null(即,该列是一个真实的值)时的值。
2. bool is_null;
这个bool型就表示这个Null<T,B>是否表示的SQL NULL。如果是SQL NULL则上述的data成员变量也变得无效了,而is_null也就成为true。
- 成员函数
这里的成员函数可以大致被分成以下几组
1. 构造函数与赋值函数
注意这里的Type表示的Null<T, B>中的T。
从这里我就发现了为什么要定义这个null_type了,可能就是为了这里的构造起来方便(上文中已经有过交代了)
2. 类型转换函数
注意这里的Behavior指的是Null<T, B>中的B,而这个默认的B就是NullIsNull结构体,在构造Null<T, B>的时候,我们可以指定这个行为。
该函数就是为了如下形式的代码而创建的
Null<sql_char, NullIsBlank> name("abc");
sql_char what_is_the_name = name; // what_is_the_name = "abc" name = mysqlpp::null;
sql_char what_is_the_name = name;
// what_is_the_name = ""
3. 比较函数
这里定义了一系列的比较操作,比如oprator ==, operator !=, operator <, operator >等。基本的法则是
1) Two null objects are equal to each other, and null is less than not-null
2) Two null objects are equal, and null is not equal to not-null. If neither is null, we delegate to operator ==
【原创】6. 在MYSQL++中实现SQL语法中的NULL的更多相关文章
- Mybatis中动态SQL语句中的parameterType不同数据类型的用法
Mybatis中动态SQL语句中的parameterType不同数据类型的用法1. 简单数据类型, 此时#{id,jdbcType=INTEGER}中id可以取任意名字如#{a,jdbcType ...
- MyBatis 中实现SQL语句中in的操作 (11)
MyBatis 中实现SQL语句中in的操作 概括:应用myBatis实现SQL查询中IN的操作 1.数据库结构及其数据 2.mapper.xml文件 <?xml version="1 ...
- PowerDesign16.6支持Mysql的生成sql脚本中包含Collate信息
当前powerDesign版本:16.6 列上指定:Collation = utf8_general_ci 但是SQL脚本中,列字段没有显示Collect ---------------------- ...
- java中的sql语句中如果有like怎么写
我先是在SQL server中写了如下语句: 这样是顺利执行的,可是我把这句话复制到Java代码中打出来却报错了, 刚开始我还以为是前端没有传回来值,待我一句一句打印发现,它提示我rs没有next.到 ...
- delphi中的sql语句中空格问题
sql语句中的冒号 ‘’,在delphi中需要用四个冒号表示 ‘’‘’,delphi中的两个冒号只代表一个冒号
- 基于mysql的一些sql语法
Sql: distinct: select distinct * from tea; Tea中每行的数据必有不同,若有两行相同的,则只输出一行 Limit: select * from stu lim ...
- sql语法中的中的with rollup
就一道ctf题分析 http://ctf5.shiyanbar.com/web/pcat/index.php 打开一看是个登陆框,首先想到的是盲注,查看源代码,有个源文件, $filter = &qu ...
- mysql系列3 SQL语法基础
1.创建数据库(语法) 2.创建(数据库)表(语法) 复制新的空表举个例子: mysql> use course;Reading table information for completion ...
- SQL语法中的JOIN类型
这个要弄明白哟..CROSS JOIN, NATURAL, INNER JOIN ,LEFT OUTER JOIN(LEFT JOIN) 等等....带LEFT,RIGHT的必为OUTER,所以OUT ...
随机推荐
- 设备上下文-CDC绘图细节
一,原理: 设备上下文是连接程序与设备(屏幕,打印机)的中介.其内部封装的函数可以使得绘图程序一次书写,在各种设备上都能显示.作用相当于多语言翻译家. 设备上下文内部封装了写文本,绘制椭圆,矩形,直线 ...
- 服务升级带来的Bug,BAT也不能幸免
这是标题党,关于阿里的,BT躺枪了. 为什么淘宝上找不到"亲淘"了? 好吧,我今天遇到了一个Bug: 立即更新,然后你看到了: 才发现亲淘不能使用了. 看官方页面: 提示:2016 ...
- ROS中使用ABB Yumi IRB14000的一些资料汇总
目前,ABB RobotStudio 已经更新到6.05.01了,可至官网下载. 使用ABB RobotStudio和ROS进行联合调试,请参考下文: http://blog.csdn.net/Zha ...
- 对结合BDD进行DDD开发的一点思考和整理
引言 二十年前的我,还在学校里抱着一台DIY机(德州486+大众主板+16M内存+3.5inch软驱+昆腾320M硬盘,当时全校最快主机没有之一),揣着一本<Undocumented DOS&g ...
- Python创建CRNN训练用的LMDB数据库文件
CRNN简介 CRNN由 Baoguang Shi, Xiang Bai, Cong Yao提出,2015年7月发表论文:"An End-to-End Trainable Neural Ne ...
- [转载] ffmpeg摄像头视频采集-采集步骤概述并采集一帧视频
近期由于工作任务,需要开发一个跨平台视频聊天系统,其中就用到了ffmpeg进行采集与编码,网上找了一大堆的资料,虽然都有一些有用的东西,但实在太碎片化了,这几天一直在整理和实验这些资料,边整理,边做一 ...
- 百度分享和bshare
社会法社交分享组件bshare http://www.bshare.cn/ 百度share也不错
- 7 函数——《Swift3.0从入门到出家
6 函数 函数就是对某个功能的封装,一个swift程序可能由多个函数组成 swift中定义函数的格式: func 函数名称(参数列表) —>函数返回值类型{ 函数体 return } 函数定义要 ...
- bzoj 1085 [SCOI2005]骑士精神——IDA*
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 迭代加深搜索. 估价函数是为了预计步数来剪枝,所以要优于实际步数. 没错,不是为了确定 ...
- Java 传递可变参数和方法重载
形式:类型... 参数名 示例:public void show(int... a) {}; 可变参数在方法中被当作数组来处理 可变参数传值的四种方式: 一个值也不传,可变参数会接收到长度为0的数组 ...