【C/C++】项目_5_MySQL与PostgreSQL数据库及数据库兼容(to_null.sql)

@TOC


1.MySQL:decimal,c/

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Navicat Premium可访问mysql数据库链接:
链接:https://pan.baidu.com/s/1otzYSvY5d08IZ5S5J-Tkzw 提取码:leof
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如上先修改完大小写参数才能创建表名时不区分大小写,mysql没有序列生成器,但有主键和索引。如下选择mysql,就不用oracle生成sql进行替换了。创建一个表,数据类型选择和oracle不一样
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

如下修改mysql字符集,大写P指端口,小写p指密码
在这里插入图片描述

以下在本地虚拟机中修改mysql字符集,如下最后一行是自己添加的
在这里插入图片描述

如下封装MySQL访问接口
在这里插入图片描述

在这里插入图片描述

# mysql头文件存放路径
MYSQLINCL = -I/usr/include/mysql

# mysql库文件保存路径
MYSQLLIB = -L/usr/lib64/mysql

# mysql链接库
MYSQLLIBS = -lmysqlclient

#CFLAGS = -O2
CFLAGS = -O2 -Wall

CFLAGS = -g -Wno-write-strings 

all:    createtable inserttable selecttable updatetable deletetable 

createtable: createtable.cpp _mysql.h _mysql.cpp
    g++ $(CFLAGS) -o createtable createtable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

inserttable: inserttable.cpp _mysql.h _mysql.cpp
    g++ $(CFLAGS) -o inserttable inserttable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

selecttable: selecttable.cpp _mysql.h _mysql.cpp
    g++ $(CFLAGS) -o selecttable selecttable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

updatetable: updatetable.cpp _mysql.h _mysql.cpp
    g++ $(CFLAGS) -o updatetable updatetable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

deletetable: deletetable.cpp _mysql.h _mysql.cpp
    g++ $(CFLAGS) -o deletetable deletetable.cpp $(MYSQLINCL) $(MYSQLLIB) $(MYSQLLIBS) _mysql.cpp -lm -lc

clean:  
    rm -rf createtable inserttable selecttable updatetable deletetable

make后./createtable


在这里插入图片描述

在这里插入图片描述

oracle用to_date,mysql用str_to_data如下


在这里插入图片描述
// 本程序演示创建一个表,用于存放商品信息createtable.cpp
#include "_mysql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("127.0.0.1,root,123qweASD!@#,mysql,3306","gbk") != 0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);

  // 准备创建表的SQL,商品表:商品编号id,商品名称name,价格sal
  // 入库时间btime,商品说明memo,商品图片pic
  // prepare方法不需要判断返回值
  stmt.prepare("\
    create table goods(id    bigint(10),\
                       name  varchar(30),\
                       sal   decimal(8,2),\
                       btime datetime,\
                       memo  longtext,\
                       pic   longblob,\
                       primary key (id))");

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  printf("create table goods ok.\n");

  return 0;
}
// 本程序演示向商品表中插入10条记录inserttable.cpp
#include "_mysql.h"

// 定义用于操作数据的结构,与表中的字段对应
struct st_GOODS
{
  long id;          // 商品编号,用long数据类型对应mysql无小数的bigint
  char name[31];    // 商品名称,用char对应mysql的varchar,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应mysql有小数的decimal
  char btime[20];   // 入库时间,用char对应mysql的datetime,格式可以在SQL语句中指定,本程序将指定为'%%Y-%%m-%%d %%h:%%i:%%s'
  char t[15];
} stgoods;

int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("127.0.0.1,root,123qweASD!@#,mysql,3306","gbk") != 0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }
  
  // SQL语言操作类
  sqlstatement stmt(&conn);
  
  // 准备插入数据的SQL,不需要判断返回值
  stmt.prepare("\
    insert into goods(id,name,sal,btime,t) \
                values(:1,:2,:3,str_to_date(:4,'%%Y-%%m-%%d %%h:%%i:%%s'),to_null(:5))");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&stgoods.id);
  stmt.bindin(2, stgoods.name,30);
  stmt.bindin(3,&stgoods.sal);
  stmt.bindin(4, stgoods.btime,19);
  stmt.bindin(5, stgoods.t,10);

  // 模拟商品数据,向表中插入10条测试信息
  for (int ii=1;ii<=10;ii++)
  {
    // 结构体变量初始化
    memset(&stgoods,0,sizeof(stgoods));

    // 为结构体的变量指定值
    stgoods.id=ii;
    sprintf(stgoods.name,"商品名称%02d",ii);
    stgoods.sal=ii*2.11;
    strcpy(stgoods.btime,"2018-03-01 12:25:31");

    // 每次指定变量的值后,执行SQL语句,一定要判断返回值,0-成功,其它-失败。
    if (stmt.execute() != 0)
    {
      printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
    }

    printf("insert ok(id=%d).\n",ii);
  }

  printf("insert table goods ok.\n");

  // 提交数据库事务
  conn.commit();

  return 0;
}
// 本程序演示从商品表中查询数据selecttable.cpp
#include "_mysql.h"
// 定义用于查询数据的结构,与表中的字段对应
struct st_GOODS
{
  long id;          // 商品编号,用long数据类型对应mysql无小数的bigint
  char name[31];    // 商品名称,用char对应mysql的varchar,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应mysql有小数的decimal
  char btime[20];   // 入库时间,用char对应mysql的datetime,格式可以在SQL语句中指定,本程序将指定为'%%Y-%%m-%%d %%h:%%i:%%s'
} stgoods;

int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("127.0.0.1,root,123qweASD!@#,mysql,3306","gbk") != 0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }
  
  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;

  // 准备查询数据的SQL,不需要判断返回值
  stmt.prepare("\
    select id,name,sal,date_format(btime,'%%Y-%%m-%%d %%h:%%i:%%s')\
      from goods where id>? and id<?");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&iminid);
  stmt.bindin(2,&imaxid);

  // 为SQL语句绑定输出变量的地址
  stmt.bindout(1,&stgoods.id);
  stmt.bindout(2, stgoods.name,30);
  stmt.bindout(3,&stgoods.sal);
  stmt.bindout(4, stgoods.btime,19);

  // 手工指定id的范围为1到8,执行一次查询
  iminid=1;
  imaxid=8;

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  while (1)
  {
    // 先把结构体变量初始化,然后才获取记录
    memset(&stgoods,0,sizeof(stgoods));

    // 获取一条记录,一定要判断返回值,0-成功,其它-无记录
    if (stmt.next() !=0) break;
    
    // 把获取到的记录的值打印出来
    printf("id=%ld,name=%s,sal=%.02f,btime=%s\n",stgoods.id,stgoods.name,stgoods.sal,stgoods.btime);
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次查询了goods表%ld条记录。\n",stmt.m_cda.rpc);
  
  return 0;
}
// 本程序演示更新商品表中数据updatetable.cpp
#include "_mysql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("127.0.0.1,root,123qweASD!@#,mysql,3306","gbk") != 0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }
   
  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;
  char strbtime[20];

  // 准备更新数据的SQL,不需要判断返回值
  stmt.prepare("\
    update goods set btime=str_to_date(:1,'%%Y-%%m-%%d %%h:%%i:%%s') where id>:2 and id<:3");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1, strbtime,19);
  stmt.bindin(2,&iminid);
  stmt.bindin(3,&imaxid);

  // 手工指定id的范围为1到5,btime为2017-12-20 09:45:30,执行一次更新
  iminid=1;
  imaxid=5;
  memset(strbtime,0,sizeof(strbtime));
  strcpy(strbtime,"2017-12-20 09:45:30");

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次更新了goods表%ld条记录。\n",stmt.m_cda.rpc);

  // 提交事务
  conn.commit();

  return 0;
}
// 本程序演示删除商品表中数据deletetable.cpp
#include "_mysql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("127.0.0.1,root,123qweASD!@#,mysql,3306","gbk") != 0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }
  
  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;

  // 准备删除数据的SQL,不需要判断返回值
  stmt.prepare("delete from goods where id>:1 and id<:2");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&iminid);
  stmt.bindin(2,&imaxid);

  // 手工指定id的范围为1到5
  iminid=1;
  imaxid=5;

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次从goods表中删除了%ld条记录。\n",stmt.m_cda.rpc); 

  // 提交事务
  conn.commit();

  return 0;
}

以下在mysql中,mysql区分空值和null值

在这里插入图片描述

如下指定c1数字型字段不是char字符串字段
在这里插入图片描述

以下在oracle中
在这里插入图片描述

在这里插入图片描述

2.PostgreSQL:头文件,$

安装:https://blog.csdn.net/zll_0405/article/details/81197633

在这里插入图片描述

在这里插入图片描述

如上设置好字符集,如下启动pg数据库,切换到pg用户并登录
在这里插入图片描述

在这里插入图片描述

PostgreSQL数据类型
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

以下在oracle中不允许
在这里插入图片描述

以下在pg中允许
在这里插入图片描述

在这里插入图片描述

如下封装pg访问接口,安装好pg数据库却找不到头文件,安装下一行
在这里插入图片描述

在这里插入图片描述

# postgresql头文件存放路径
PGINCL = -I/usr/include

# postgresql库文件保存路径
PGLIB = -L/usr/lib64

# postgresql链接库
PGLIBS = -lpq

#CFLAGS = -O2
CFLAGS = -O2 -Wall
#CFLAGS = -g -Wall
CFLAGS = -g -Wno-write-strings

all:    createtable inserttable selecttable updatetable deletetable

createtable: createtable.cpp _postgresql.h _postgresql.cpp
    g++ $(CFLAGS) -o createtable createtable.cpp _postgresql.cpp  $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc

inserttable: inserttable.cpp _postgresql.h _postgresql.cpp
    g++ $(CFLAGS) -o inserttable inserttable.cpp _postgresql.cpp  $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc

selecttable: selecttable.cpp _postgresql.h _postgresql.cpp
    g++ $(CFLAGS) -o selecttable selecttable.cpp _postgresql.cpp  $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc

updatetable: updatetable.cpp _postgresql.h _postgresql.cpp
    g++ $(CFLAGS) -o updatetable updatetable.cpp _postgresql.cpp  $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc

deletetable: deletetable.cpp _postgresql.h _postgresql.cpp
    g++ $(CFLAGS) -o deletetable deletetable.cpp _postgresql.cpp  $(PGINCL) $(PGLIB) $(PGLIBS) -lm -lc

clean:  
    rm createtable inserttable selecttable updatetable deletetable
// 本程序演示创建一个表,用于存放商品信息createtable.cpp
#include "_postgresql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;

  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("host=118.89.50.198 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);

  // 准备创建表的SQL,商品表:商品编号id,商品名称name,价格sal
  // 入库时间btime,商品说明memo,商品图片pic
  // prepare方法不需要判断返回值
  stmt.prepare("\
    create table goods(id    int,\
                       name  varchar(30),\
                       sal   numeric(8,2),\
                       btime timestamp,\
                       memo  text,\
                       pic   bytea)");
  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  // 提交事务,注意,在postgresql数据库中,创建表也要提交事务,但删除表却不用,奇怪
  conn.commitwork();

  printf("create table goods ok.\n");

  return 0;
}
// 本程序演示向商品表中插入10条记录inserttable.cpp
#include "_postgresql.h"
// 定义用于操作数据的结构,与表中的字段对应
struct st_GOODS
{
  long id;          // 商品编号,用long数据类型对应postgresql无小数的int
  char name[31];    // 商品名称,用char对应postgresql的varchar,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应postgresql有小数的numeric
  char btime[20];   // 入库时间,用char对应postgresql的timestamp,格式可以在SQL语句中指定,本程序将指定为'yyyy-mm-dd hh24:mi:ss'
} stgoods;

int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;

  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("host=118.89.50.198 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);
  
  // 准备插入数据的SQL,不需要判断返回值
  stmt.prepare("\
    insert into goods(id,name,sal,btime)\
               values(:1,:2,:3,to_timestamp(:4,'yyyy-mm-dd hh24:mi:ss'))");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&stgoods.id);
  stmt.bindin(2, stgoods.name,30);
  stmt.bindin(3,&stgoods.sal);
  stmt.bindin(4, stgoods.btime,19);
  
  // 模拟商品数据,向表中插入10条测试信息
  for (int ii=1;ii<=10;ii++)
  {
    // 结构体变量初始化
    memset(&stgoods,0,sizeof(stgoods));
  
    // 为结构体的变量指定值
    stgoods.id=ii;
    sprintf(stgoods.name,"商品名称%02d",ii);
    stgoods.sal=ii*2.11;
    strcpy(stgoods.btime,"2018-03-01 12:25:31");
  
    // 每次指定变量的值后,执行SQL语句,一定要判断返回值,0-成功,其它-失败。
    if (stmt.execute() != 0)
    {
printf("id=%d\n",stgoods.id);
      printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
    }
  
    printf("insert ok(id=%d).\n",ii);
  }
  
  printf("insert table goods ok.\n");

  // 提交数据库事务
  conn.commitwork();
  
  return 0;
}  
// 本程序演示更新商品表中数据updatetable.cpp
#include "_postgresql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("host=118.89.50.198 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;
  char strbtime[20];

  // 准备更新数据的SQL,不需要判断返回值
  stmt.prepare("\
    update goods set btime=to_date(:1,'yyyy-mm-dd hh24:mi:ss') where id>:2 and id<:3");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1, strbtime,19);
  stmt.bindin(2,&iminid);
  stmt.bindin(3,&imaxid);

  // 手工指定id的范围为1到5,btime为2017-12-20 09:45:30,执行一次更新
  iminid=1;
  imaxid=5;
  memset(strbtime,0,sizeof(strbtime));
  strcpy(strbtime,"2017-12-20 09:45:30");

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次更新了goods表%ld条记录。\n",stmt.m_cda.rpc);

  // 提交事务
  conn.commitwork();

  return 0;
}
// 本程序演示从商品表中查询数据selecttable.cpp
#include "_postgresql.h"
// 定义用于操作数据的结构,与表中的字段对应
struct st_GOODS
{ 
  long id;          // 商品编号,用long数据类型对应postgresql无小数的int
  char name[31];    // 商品名称,用char对应postgresql的varchar,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应postgresql有小数的numeric
  char btime[20];   // 入库时间,用char对应postgresql的timestamp,格式可以在SQL语句中指定,本程序将指定为'yyyy-mm-dd hh24:mi:ss'
} stgoods;

int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败,失败代码在conn.m_cda.rc中
  // 失败描述在conn.m_cda.message中。
  if (conn.connecttodb("host=118.89.50.198 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;

  // 准备查询数据的SQL,不需要判断返回值
  stmt.prepare("\
    select id,name,sal,to_char(btime,'yyyy-mm-dd hh24:mi:ss')\
      from goods where id>:1 and id<:2");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&iminid);
  stmt.bindin(2,&imaxid);

  // 为SQL语句绑定输出变量的地址
  stmt.bindout(1,&stgoods.id);
  stmt.bindout(2, stgoods.name,30);
  stmt.bindout(3,&stgoods.sal);
  stmt.bindout(4, stgoods.btime,19);

  // 手工指定id的范围为1到5,执行一次查询
  iminid=1;
  imaxid=8;

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  while (1)
  {
    // 先把结构体变量初始化,然后才获取记录
    memset(&stgoods,0,sizeof(stgoods));

    // 获取一条记录,一定要判断返回值,0-成功,其它-无记录
    if (stmt.next() !=0) break;
    
    // 把获取到的记录的值打印出来
    printf("id=%ld,name=%s,sal=%.02f,btime=%s\n",stgoods.id,stgoods.name,stgoods.sal,stgoods.btime);
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次查询了goods表%ld条记录。\n",stmt.m_cda.rpc);
  
  return 0;
}
// 本程序演示删除商品表中数据deletetable.cpp
#include "_postgresql.h"
int main(int argc,char *argv[])
{
  // 数据库连接池
  connection conn;
  
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("host=118.89.50.198 user=postgres password=pwdidc dbname=postgres port=5432","gbk")!=0)
  {
    printf("connect database failed.\n%s\n",conn.m_cda.message); return -1;
  }

  // SQL语言操作类
  sqlstatement stmt(&conn);

  int iminid,imaxid;

  // 准备删除数据的SQL,不需要判断返回值
  stmt.prepare("delete from goods where id>:1 and id<:2");
  // 为SQL语句绑定输入变量的地址
  stmt.bindin(1,&iminid);
  stmt.bindin(2,&imaxid);

  // 手工指定id的范围为1到5
  iminid=1;
  imaxid=5;

  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。
  if (stmt.execute() != 0)
  {
    printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;
  }

  // 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。
  printf("本次从goods表中删除了%ld条记录。\n",stmt.m_cda.rpc); 

  // 提交事务
  conn.commitwork();

  return 0;
}
在这里插入图片描述

3.数据库兼容:to_null.sql

oracle,mysql,pg数据库代码除了sql语句部分,其他完全一样。如下pg用/d 表名查看表结构

在这里插入图片描述

在这里插入图片描述

让字段为空,sql用null,程序中用一个变量绑定字段,数字型变量(不管整数还是浮点数)表达不了空
在这里插入图片描述

在这里插入图片描述

只有oracle可以delete goods不加from,并且oracle需要提交
在这里插入图片描述

在这里插入图片描述

如上三种数据库都为0,不为空,因为C语言中数字型变量表达不了空,所以实际开发中用字符串和字段绑定起来。如下还给t字段赋值10
在这里插入图片描述

如下三种数据库t字段都为10
在这里插入图片描述

如下改参数解决自动转换也不行
在这里插入图片描述

数据处理程序一旦涉及空字段的话,在不同数据库之间迁移,基本要重写,如下甚至连绑定字段也用不了
在这里插入图片描述

上面方法虽然解决了null,但很多记录字段有时为空,有时不为空,要先去判断字段是否为空再去拼接sql,效率低,程序烦。三种数据库对varchar()和decimal()做兼容处理,oracle的空和null没区别,mysql和pg有区别
在这里插入图片描述

在这里插入图片描述

0转换为null,自定义数据库函数to_null
在这里插入图片描述

在这里插入图片描述

如下mysql的to_null函数放在程序中不行,所以mysql用上面方法
在这里插入图片描述

如下是函数的兼容
在这里插入图片描述

在这里插入图片描述

mysql本身自增列字段意义不大,没有序列生成器但可模拟出:https://www.runoob.com/mysql/mysql-using-sequences.html
在这里插入图片描述

SQL Server:C语言访问SQL Server两种方式:ct/db-library,freetds

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 什么是数据库? 数据库是存储数据的集合的单独的应用程序。每个数据库具有一个或多个不同的API,用于创建,访问,管理...
    chen_000阅读 4,030评论 0 19
  • 1.MySQL数据库 2.SQL语句 第一节课 ###1(MySQL数据库)数据库概念.avi 5...
    码了个农啵阅读 1,194评论 1 16
  • MySQL技术内幕:SQL编程 姜承尧 第1章 SQL编程 >> B是由MySQL创始人之一Monty分支的一个版...
    沉默剑士阅读 2,405评论 0 3
  • MySQL5.6从零开始学 第一章 初始mysql 1.1数据库基础 数据库是由一批数据构成的有序的集合,这些数据...
    星期四晚八点阅读 1,133评论 0 4
  • 一. Java基础部分.................................................
    wy_sure阅读 3,790评论 0 11