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用户exit
或ctrl+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)