C/C++8天气APP:Oracle数据库安装,表操作,C语言操作Oracle数据库

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++8天气APP:Oracle数据库安装,表操作,C语言操作Oracle数据库相关的知识,希望对你有一定的参考价值。


1.安装:swap,find

1.1 创建swap交换区

#grep MemTotal /proc/meminfo (安装Oracle物理内存要求1024MB以上)。
#grep SwapTotal /proc/meminfo (下面是交换区要求)。

下面为添加交换区大小,此方法不限于centos,linux均适用,以下命令均需在root帐号下操作:
(1)先用free -m查看一下swap的大小。

(2)使用dd命令创建/home/swap这么一个分区文件。
#dd if=/dev/zero of=/home/swap bs=1024 count=2048000

(3)接着再把这个分区变成swap分区。
#/sbin/mkswap /home/swap

(4)再接着使用这个swap分区。使其成为有效状态。
#/sbin/swapon /home/swap

(5)现在再用free -m命令查看一下内存和swap分区大小,就发现增加了2048M的空间了。创建的是2048,显示1999。

(6)修改/etc/fstab文件,让CentOS操作系统在每次重启时自动加载/home/swap交换区。
#vi /etc/fstab,/home/swap swap swap defaults 0 0

(上面执行错可以删除交换分区,对了不用删)
停止正在使用的swap分区:#swapoff /home/swap
删除swap分区文件:#rm /home/swap
删除或注释在/etc/fstab文件开机自动挂载/swap1的命令。

1.2 安装依赖包及改系统核心参数

yum install -y binutils* compat-libstdc* elfutils-libelf* gcc* glibc* ksh* libaio* libgcc* libstdc* make* sysstat* libXp* glibc-kernheaders
yum install -y ksh binutils compat-libstdc+±33 elfutils-libelf elfutils-libelf-devel gcc gcc-c++ glibc glibc-common glibc-devel libaio libaio-devel libgcc libstdc++ libstdc+±devel make numactl sysstat libXp unixODBC unixODBC-devel
(修改系统核心参数,关闭一些系统对数据库的限制)
1.修改/etc/sysctl.conf文件。
#vi /etc/sysctl.conf
在文件最后增加以下行。
fs.file-max = 6815744
fs.aio-max-nr = 1048576
kernel.shmall = 2097152
kernel.shmmax= 2147483648
kernel.shmmni= 4096
kernel.sem = 250 32000100 128
net.ipv4.ip_local_port_range= 9000 65500
net.core.rmem_default= 262144
net.core.rmem_max= 4194304
net.core.wmem_default = 262144
net.core.wmem_max= 1048576
注意,kernel.shmmax参数的值为操作系统内存的一半,单位是字节。例如,装服务器的总物理内存如果是1024MB,那么kernel.shmmax的值应该是512乘1024乘1024=536870912,即kernel.shmmax = 536870912,其它的参数照抄。
2. 修改/etc/security/limits.conf文件。
#vi /etc/security/limits.conf
修改操作系统对oracle用户资源的限制。在该文件中添加如下行:
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
oracle hard stack 10240
3.修改/etc/pam.d/login文件。
添加如下的行到/etc/pam.d/login文件
#vi /etc/pam.d/login
session required /lib/security/pam_limits.so
4.修改/etc/profile文件。
添加如下的行到/etc/profile文件
#vi /etc/profile

if [ $USER = "oracle" ]; then
        if [ $SHELL = "/bin/ksh" ]; then
              ulimit -p 16384
              ulimit -n 65536
        else
              ulimit -u 16384 -n 65536
        fi
fi

5.关闭 selinux。
#vi /etc/selinux/config,修改成 selinux=disabled
6.关闭图形界面。
#vi /etc/inittab,把最后一行运行级别改为3,没有的话就不执行这一步

7.重启服务器 #init 6 或 reboot。

1.3 创建oracle用户和组及解压缩包

以下命令都在root用户执行:增加dba组:groupadd dba(相同等级的用户放一起就是一个组,只要对组设定权限就行)。useradd -n oracle -g dba -d /oracle:增加oracle用户(这种方法创建oracle用户,会在根目录形成单独oracle文件夹与home和root文件夹平级,普通创建用户useradd y在根目录里的home目录里形成y文件夹)。

passwd oracle:修改oracle用户的密码。cat /etc/passwd:查看所有用户除root。cat /etc/group:查看所有用户组。groups 用户名:查看用户所在组。userdel (-r)用户名:删除用户(或删除home文件夹里用户名文件夹)。

Linux 中,操作系统会根据UID 来判断用户,如果id 为0则为管理员账户,可能存在多个管理员账户。每个用户都会属于一个组,意味着当创建用户的时候,系统会自动创建一个同名组作为次账户的主组。用户和组的关系以配置文件的方式关联,相关配置文件如下:


从win本地上传oracle11g1.tgz压缩包到linux的tmp目录。用oracle用户登录,从根目录下开始解开压缩包,链接:https://pan.baidu.com/s/1Ywtv8zzRGzSCpwu9PyPobQ 提取码:ebk7 。#cd / #tar zxvf /tmp/oracle11g.tgz。



解压缩包后,一定要退出oracle用户exitctrl+d,否则oracle用户的环境变量不会生效。oracle11gR2.tgz解压后,会生成/oracle/.bash_profile文件,包括了Oracle数据库的安装参数,内容如下:

export ORACLE_BASE=/oracle/base
export ORACLE_HOME=/oracle/home
export ORACLE_SID=snorcl11g
export NLS_LANG='Simplified Chinese_China.ZHS16GBK'
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib
export PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin:.

1.4 数据库的启动和关闭

用oracle用户登录,执行lsnrctl start启动网络监听服务,执行dbstart启动数据库系统。
用oracle用户登录,执行lsnrctl stop关闭网络监听服务,执行dbshut关闭数据库系统。lsnrctl status,在关服务器操作系统之前,一定要关闭数据库,否则数据库损坏的概率超过50%。
Oracle数据库的启动和关闭配置成系统服务:在操作系统启动/关闭时自动启动/关闭Oracle实例和监听,以下都在root用户操作:
1.启动数据库实例的SQL脚本:vi /oracle/home/bin/dbstart

sqlplus / as sysdba <<EOF
startup;
EOF

chmod +x /oracle/home/bin/dbstart
2.vi /oracle/home/bin/dbrestart

sqlplus / as sysdba <<EOF
shutdown immediate;
startup;
EOF

chmod +x /oracle/home/bin/dbrestart
3.vi /oracle/home/bin/dbshut

sqlplus / as sysdba <<EOF
shutdown immediate;
EOF

chmod +x /oracle/home/bin/dbshut
4.vi /usr/lib/systemd/system/oracle.service(/usr/lib文件夹里有一些.so文件,/systemd/system/oracle.service是自己创建的)

[Unit]
Description=Oracle RDBMS
After=network.target
 
[Service]
Type=simple
ExecStart=/usr/bin/su - oracle -c "/oracle/home/bin/dbstart >> /tmp/oracle.log"
ExecReload=/usr/bin/su - oracle -c "/oracle/home/bin/dbrestart >> /tmp/oracle.log"
ExecStop=/usr/bin/su - oracle -c "/oracle/home/bin/dbshut >> /tmp/oracle.log"
RemainAfterExit=yes
 
[Install]
WantedBy=multi-user.target

vi /usr/lib/systemd/system/lsnrctl.service

[Unit]
Description=Oracle RDBMS
After=network.target
 
[Service]
Type=simple
ExecStart=/usr/bin/su - oracle -c "/oracle/home/bin/lsnrctl start >> /tmp/lsnrctl.log"
ExecReload=/usr/bin/su - oracle -c "/oracle/home/bin/lsnrctl reload >> /tmp/lsnrctl.log"
ExecStop=/usr/bin/su - oracle -c "/oracle/home/bin/lsnrctl stop >> /tmp/lsnrctl.log"
RemainAfterExit=yes
 
[Install]
WantedBy=multi-user.target

5.如下命令可不执行。
systemctl daemon-reload # 重新加载服务配置文件
systemctl start oracle # 启动oracle服务。
systemctl restart oracle # 重启oracle服务。
systemctl stop oracle # 关闭oracle服务。
systemctl start lsnrctl # 启动lsnrctl服务。
systemctl restart lsnrctl # 重启lsnrctl服务。
systemctl stop lsnrctl # 关闭lsnrctl服务。
6.systemctl enable oracle # 把Oracle实例服务设置为开机自启动。
systemctl enable lsnrctl # 把Oracle监听服务设置为开机自启动。
7.Oracle实例启动的日志在/tmp/oracle.log文件中。监听的启动日成在/tmp/lsnrctl.log文件中。只有通过systemctl启动/关闭Oracle实例和监听才会写日志,手工执行脚本不写日志。

1.5 sqlplus命令行登录数据库

用oracle用户登录,执行sqlplus scott/tiger,以scott用户的身份登录数据库。防火墙放开1521端口sqlplus登录数据库,centos7和centos6的防火墙设置不同,centos7采用以下方法:systemctl restart firewalld.service设完端口前后防火墙都重启下,firewall-cmd --list-ports查下放开的端口。
#firewall-cmd --zone=public --add-port=1521/tcp --permanent

启动监听:lsnrctl status,如下关闭防火墙:


sqlplus中实现命令的上翻下翻功能:https://centos.pkgs.org/ 下载rlwrap-0.37.tar或百度云链接:https://pan.baidu.com/s/1CgO-_To-QLdl1CJJM-ZrBA 提取码:k6cu。

root用户执行:tar -zxvf rlwrap-0.37.tar.gz,cd rlwrap-0.37/,yum install -y libtermcap-devel,yum -y install readline*, ./configure,make,make install,rlwrap -v ,which rlwrap,su - oracle ,vi .bash_profile(root用户vi ~/.bash_profile不行),文件最后加上如下两行(=号前后无空格,英文单引号)
alias sqlplus=‘rlwrap sqlplus’
alias rman=‘rlwrap rman’
source .bash_profile并重新打开oracle用户窗口。

1.6 plsql客户端登录数据库

1.客户端环境:https://www.oracle.com/technetwork/database/enterprise-edition/downloads/112010-win64soft-094461.html?ssSourceSiteId=otncn
win64_11gR2_client链接:https://pan.baidu.com/s/1xLzrXAZm3xM-szds1IoQFw,提取码:mlo8 ,解压后点击set up应用程序进行安装。

2.客户端界面:链接:https://pan.baidu.com/s/1H9WIojcMbyqTBZe_goO-1Q 提取码:fp2u ,点击直接安装,桌面显示如下粉色图标。


3.客户端参数配置文件
D:\\app\\w\\product\\11.2.0\\client_1\\network\\admin\\tnsnames.ora(可以搜索tnsnames.ora)

snorcl11g_138 =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.149.138)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SID = snorcl11g)
      (SERVER = DEDICATED)
    )
  )

如上是客户端如下是服务端,参数内容与上相同。

snorcl11g_138:是随便起的,远程连接需打开监听lsnrctl start。

RDBMS:关系数据库管理系统,实例名就是SID。

2.表操作:tnsping,commit

主键比如编号,不能是姓名(可能重名)。



2.1 建create


如果id用number,前面的0会被省去。C语言中字符串结尾要空字符结束,数据库中不要。

2.2 增insert



主键不能为空,null为空,0就是数字0。

2.3 删delete


上面为删除表,下面为删除表中数据。

2.4 改update

2.5 查select




不在同一网段内(局域网内)称远程,ssh客户端和sqldeveloper客户端都存在不操作会断开(TCP连接)。因为日期在oracle里实质是个整数,显示书写是字符串。to_data转为整数。


数据库中置为空为null不为0(或者给’ ')。C语言中0和null一样(C中字符串可为空,整数没办法为空)。

select * from tab;(F8运行如下)。


升序后面加asc,默认升序不写。

to_data:字符串日期转为oracle日期(以数据存储)
to_char:oracle日期(以数据存储)转为字符串,如上格式转为如下格式。



长事务指时间长如update一条记录在那等处理,等完后再提交,锁也属于一种资源,锁的总数有限。DBA也会定期整理碎片,windows中管理工具中也有个碎片整理。

4.C语言操作Oracle:trim,rc,库/头文件

4.1 oci

C/C++操作数据库有两种方法:1.Pro*C(在C/C++中嵌入SQL语句),2.OCI(用C语言调用oracle库函数)。关于封装好的OCI代码见文章:https://blog.csdn.net/weixin_43435675/article/details/105594808。_ooci.h中第一个类connection:数据库连接池类,第二个类sqlstatement:sql语言操作数据库类,如下rc执行结果成功为0,失败为oracle错误代码,并将其错误信息放入message,下面在_ooci.h中。


程序里每执行一条sql就会提交一次事务,因为没有多表操作,只要把数据插入这张表中就可以了,有没有事务无所谓,缺省0:启动事务。

如下下面两行=上面一行,conn用的哪个(不是哪种)数据库的connection类。conn指针和conn类实例同名,&conn类实例,实例化时调用含参的构造函数。

4.2 makefile

#oracle头文件路径  #-I指定头文件的搜索目录/oracle/home/rdbms/public。装了oracle数据库的主机,不管这主机上任何用户名字,都有/oracle/home/rdbms/public这路径 
ORAINCL = -I$(ORACLE_HOME)/rdbms/public

# oracle库文件路径  #-L指定库文件的搜索目录/oracle/home/lib
ORALIB =  -L$(ORACLE_HOME)/lib -L.

# oracle的oci库  #-l指定链接库名libclntsh.so
ORALIBS = -lclntsh

CFLAGS = -g -Wno-write-strings -Wno-unused-variable

all: createtable inserttable selecttable updatetable deletetable execplsql

createtable:createtable.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o createtable createtable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

inserttable:inserttable.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o inserttable inserttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

selecttable:selecttable.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o selecttable selecttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

updatetable:updatetable.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o updatetable updatetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

deletetable:deletetable.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o deletetable deletetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

execplsql:execplsql.cpp _ooci.h _ooci.cpp
        g++ $(CFLAGS) -o execplsql execplsql.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

-Wno-write-string没有这行的话可将createtable.cpp中警告的字符串前加上(char*)就行。还可以在声明时_ooci.h加const,_ooci.cpp中也要修改(不建议)。-Wno-unused-variable变量未使用关闭警告(如int cc;下面未使用cc变量)。



如下-g是可调试,clntsh是真正的库名,lib.so动态库命名(静态库lib.a,静态库代码在编译时被整合到程序里,编译完成静态库删了没问题)

动态库是执行到相关函数时才调用该函数库里相应函数,函数库没有整合进程序里(因为没有整合进程序,如1000个程序链接共享动态库,这样可执行文件会小很多,节省内存)

优点是动态库改变不影响程序,程序不需要重新编译,只需要重新编译动态库就行。

头路径,库路径,库名(.a/.so/.cpp),如下头文件采用-I标准写法,库文件不采用标准也写法编译也过。

如下全部采用标准写法。

如下采用原始不含头文件编译方法错误。


下面是文件:

如下采用ORACLE_HOME换用户时只需要添加该用户.bash_profile中export…进env,不需要改makefile。



下面是文件:


如下程序只要链接了动态库就需要LD…这个环境变量(属于linux操系环变,不属于oracle数据库环变)。

4.3 createtable.cpp

#include "_ooci.h"
int main(int argc,char *argv[])

//11111111111111111111111111111111111111111111111111111111.数据库连接池类
  connection conn;
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("scott/tiger@snorcl11g_138","Simplified Chinese_China.ZHS16GBK") != 0)
  
    printf("connect database failed.\\n%s\\n",conn.m_cda.message); return -1;
  

//11111111111111111111111111111111111111111111111112.SQL语言操作类
  sqlstatement stmt(&conn);  //不需要判断返回值
  // 准备创建表的SQL,商品表:商品编号id,商品名称name,价格sal,入库时间btime,商品说明memo,商品图片pic
  // prepare方法不需要判断返回值
  stmt.prepare("\\
    create table goods(id    number(10),\\
                       name  varchar2(30),\\
                       sal   number(10,2),\\
                       btime date,\\
                       memo  clob,\\
                       pic   blob,\\
                       primary key (id))");

//111111111111111111111111111111111111111111111113.执行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;


setenv/putenv设置环境变量,下面这个类也是可以兼容windows。

如下commit失败的话也会调用m_cda结构体,goods为表名,如下(id))后面不需要分号,sqlplus里需要分号且把\\去除,prepare语法和printf语法一样如下有%s(也叫动态参数)。如下execute()是有参数或无参数的重载函数,insert要提交。


如下trim(c1)去除c1的空格,最后一行不加trim是查不出下面表格。char补空格,varchar不补空格。确定长度用char(char好处快),c1 varchar2(4000)用到几个字符自动分配几个而不是一下给4000字符。CLOB:结构化数据如文本信息。BLOB:非结构化数据。

4.4 inserttable.cpp

// 本程序演示向商品表中插入10条记录。
#include "_ooci.h"
// 定义用于操作数据的结构,与表中的字段对应
struct st_GOODS  //结构体值与数据库中表即与createtable.cpp中表对应

  long id;          // 商品编号,用long数据类型对应oracle无小数的number
  char name[31];    // 商品名称,用char对应oracle的varchar2,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应oracle有小数的number
  char btime[20];   // 入库时间,用char对应oracle的date,格式可以在SQL语句中指定,本程序将指定为yyyy-mm-dd hh24:mi:ss
 stgoods;

int main(int argc,char *argv[])

//111111111111111111111111111111111111111111111111.数据库连接池
  connection conn;
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。
  if (conn.connecttodb("scott/tiger@snorcl11g_138","Simplified Chinese_China.ZHS16GBK") != 0)
  
    printf("connect database failed.\\n%s\\n",conn.m_cda.message); return -1;
  
    
//111111111111111111111111111111111111111111111112.SQL语言操作类
  sqlstatement stmt(&conn);
  // 准备插入数据的SQL,不需要判断返回值
  stmt.prepare("\\
    insert into goods(id,name,sal,btime) \\
                values(:1,:2,:3,to_date(:4,'yyyy-mm-dd hh24:mi:ss'))");
                //to_date(:4,'yyyy-mm-dd hh24:mi:ss')可为null
                //goods(id,name,sal,btime)字段在createtable.cpp已创建
  // 为SQL语句绑定输入变量的地址,行
  stmt.bindin(1,&stgoods.id);//bindin中的1对应上面:1
  stmt.bindin(2, stgoods.name,30); //30为长度,char是这样绑定
  stmt.bindin(3,&stgoods.sal);  //此时stgoods.id结构体变量们还未赋值
  stmt.bindin(4, stgoods.btime,19);

//111111111111111111111111111111111111111111111113.模拟商品数据,向表中插入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) //每执行一次把变量值插入表,返回结构体m_cda.rc
    
      printf("stmt.execute() failed.\\n%s\\n%s\\n",stmt.m_sql,stmt.m_cda.message); return -1;
    
    printf("insert ok(id=%d,rpc=%ld).\\n",ii,stmt.m_cda.rpc); //rpc为行数
  
  printf("insert table goods ok.\\n");
  // 提交数据库事务,不提交的话程序退出,缺省回滚事务
  conn.commit();
  return 0;


select count(*) from。



下图因为id唯一,所以不能重复插入。错误信息与上面一行对应。

truncate table goods删除表中全部数据,但是不产生事务。若注释//conn.commit();则insert后查询无记录,如下开启自动提交。


make后./inserttable。

4.5 selecttable.cpp

//本程序演示从商品表中查询数据
#include "_ooci.h"
// 定义用于查询数据的结构,与表中的字段对应
struct st_GOODS  //和inserttable.cpp中结构体一样

  long id;          // 商品编号,用long数据类型对应oracle无小数的number
  char name[31];    // 商品名称,用char对应oracle的varchar2,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符
  double sal;       // 商品价格,用double数据类型对应oracle有小数的number
  char btime[20];   // 入库时间,用char对应oracle的date,格式可以在SQL语句中指定,本程序将指定为yyyy-mm-dd hh24:mi:ss
 stgoods;

int main(int argc,char *argv[])

//111111111111111111111111111111111111111111111111.数据库连接池
  connection conn; 
  // 连接数据库,返回值0-成功,其它-失败
  // 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中
  if (conn.connecttodb("scott/tiger@snorcl11g_138","Simplified Chinese_China.ZHS16GBK") != 0)
  
    printf("connect database failed.\\n%s\\n",conn.m_cda.message); return -1;
  
    
//111111111111111111111111111111111111111111111112.SQL语言操作类
  sqlstatement stmt(以上是关于C/C++8天气APP:Oracle数据库安装,表操作,C语言操作Oracle数据库的主要内容,如果未能解决你的问题,请参考以下文章

C/C++10天气APP:MySQL,PostgreSQL,环境变量,动静态库,Linux/Oracle字符集

C/C++11天气APP:txt/xml文件处理入库(psurfdata.cpp,_shqx.h),数据结构设计(PowerDesigner)

C/C++13天气APP:数据挖掘/HTTP协议/非结构化数据存储(filetoblob.cpp),数据管理/监控告警(hsmtable.cpp,tbspaceinfo.cpp)

C/C++15天气APP:服务端(client.cpp,shtqappserver.cpp)

C/C++7天气APP:生成观测数据txt/xml文件(crtsurfdata.cpp),ftp协议及ftp采集模块(_ftp.h,_ftp.cpp,ftpgetfiles.cpp)

C/C++12天气APP:不同数据建表入表,数据交换(exptables.cpp,ftpputfiles.cpp)