【database3】oracle:数据交换/存储/收集

文章目录

  • 1.oracle安装:swap,dd
    • 1.1 创建swap交换区:grep MemTotal /proc/meminfo (安装Oracle物理内存要求1024MB以上),grep SwapTotal /proc/meminfo
    • 1.2 安装依赖包及改系统核心参数:关闭一些系统对数据库的限制,pam.d,inittab
    • 1.3 数据库的启动和关闭:oracle用户登录,lsnrctl start/stop/status 启动/关闭网络监听服务,dbstart/dbshut 启动/关闭数据库
    • 1.4 sqlplus命令行登录数据库:用oracle用户登录,执行sqlplus scott/tiger,以scott用户的身份登录
    • 1.5 plsql客户端登录数据库:远程连接需打开监听lsnrctl start
  • 2.C语言操作oracle:trim,rc,库/头文件
    • 2.1 makefile:-Wno-unused-variable变量未使用关闭警告(如int cc;下面未使用cc变量)
    • 2.2 createtable.cpp:setenv/putenv设置环境变量,char补空格,varchar不补空格。确定长度用char快,varchar2(4000)用到几个字符自动分配几个而不是一下给4000字符
    • 2.3 inserttable.cpp:truncate删除表中全部数据,不产生事务
    • 2.4 selecttable.cpp:stmt.m_cda.rpc变量保存了SQL执行后影响的记录数
    • 2.5 updatetable.cpp:连接数据库,返回值0成功,其它失败,失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中
    • 2.6 deletetable.cpp:删除商品表中数据
    • 2.7 execplsql.cpp:执行一个PL/SQL过程
  • 3.虚表/日期/序列:ntp&hwclock
  • 4.索引/视图/链路/同义词:create index/view/link/synonym,distinct
  • 5.系统高可用性:12个1T组合,rac
  • 6.txt/xml文件入表:结构体内容
  • 7.站点参数建表入表/PowerDesigner/主外键:多表查询
  • 8.数据交换:数据导出为文件,数据文件推送
  • 9.非结构化数据存储:blob,pzhrain24file
  • 10.磁盘/cpu信息收集:内存信息free -m,和top命令查看的内存是一样的,也在系统文件/proc/meminfo


1.oracle安装:swap,dd

1.1 创建swap交换区:grep MemTotal /proc/meminfo (安装Oracle物理内存要求1024MB以上),grep SwapTotal /proc/meminfo

在这里插入图片描述
下面为添加交换区大小,此方法不限于centos,linux均适用,以下命令均需在root帐号下操作:
(1)先用free -m查看一下swap的大小。
在这里插入图片描述
(2)使用dd命令创建/home/swap这么一个分区文件。
在这里插入图片描述
(3)接着再把这个分区变成swap分区。
在这里插入图片描述
(4)再接着使用这个swap分区。使其成为有效状态。
在这里插入图片描述
(5)现在再用free -m命令查看一下内存和swap分区大小,就发现增加了2048M的空间了。创建的是2048,显示1999。
在这里插入图片描述
(6)修改/etc/fstab文件,让CentOS操作系统在每次重启时自动加载/home/swap交换区。上面执行错可以删除交换分区rm /home/swap,对了不用删。停止正在使用的swap分区:swapoff /home/swap。
在这里插入图片描述

1.2 安装依赖包及改系统核心参数:关闭一些系统对数据库的限制,pam.d,inittab

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.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.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.vi /etc/pam.d/login。
session required /lib/security/pam_limits.so
4.vi /etc/profile。

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

5.vi /etc/selinux/config,修改成 selinux=disabled。
6.关闭图形界面,vi /etc/inittab,把最后一行运行级别改为3,没有的话就不执行这一步。
在这里插入图片描述
7.重启服务器 #init 6 或 reboot。

从win本地上传oracle11g1.tgz压缩包到linux的tmp目录。用oracle用户登录,从根目录下开始解开压缩包,链接:https://pan.baidu.com/s/1Ywtv8zzRGzSCpwu9PyPobQ,提取码:ebk7 。
在这里插入图片描述
解压缩包后,一定要退出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.3 数据库的启动和关闭:oracle用户登录,lsnrctl start/stop/status 启动/关闭网络监听服务,dbstart/dbshut 启动/关闭数据库

oracle数据库的启动和关闭配置成系统服务:在操作系统启动/关闭时自动启动/关闭Oracle实例和监听,以下都在root用户操作:
1.启动数据库实例的SQL脚本:vi /oracle/home/bin/dbstart,chmod +x

sqlplus / as sysdba <<EOF
startup;
EOF

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

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

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

sqlplus / as sysdba <<EOF
shutdown immediate;
EOF

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.4 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,如下关闭防火墙:
在这里插入图片描述

1.5 plsql客户端登录数据库:远程连接需打开监听lsnrctl start

1.客户端环境: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

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

如上是客户端,如下是服务端,参数内容与上相同,snorcl11g_138:是随便起的。
在这里插入图片描述

2.C语言操作oracle:trim,rc,库/头文件

2.1 makefile:-Wno-unused-variable变量未使用关闭警告(如int cc;下面未使用cc变量)

#oracle头文件路径
ORAINCL = -I$(ORACLE_HOME)/rdbms/public# oracle库文件路径  #-L指定库文件的搜索目录/oracle/home/lib
ORALIB =  -L$(ORACLE_HOME)/lib -L.# oracle的oci库  #-l指定链接库名libclntsh.so
ORALIBS = -lclntshCFLAGS = -g -Wno-write-strings -Wno-unused-variableall: createtable inserttable selecttable updatetable deletetable execplsqlcreatetable:createtable.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o createtable createtable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cppinserttable:inserttable.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o inserttable inserttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cppselecttable:selecttable.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o selecttable selecttable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cppupdatetable:updatetable.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o updatetable updatetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cppdeletetable:deletetable.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o deletetable deletetable.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cppexecplsql:execplsql.cpp _ooci.h _ooci.cppg++ $(CFLAGS) -o execplsql execplsql.cpp $(ORAINCL) $(ORALIB) $(ORALIBS) _ooci.cpp

-Wno-write-string没有这行的话可将createtable.cpp中警告的字符串前加上(char*)就行。
在这里插入图片描述
还可以在声明时_ooci.h加const,_ooci.cpp中也要修改(不建议)。
在这里插入图片描述
如下-g是可调试。
在这里插入图片描述
如下全部采用标准写法:头路径,库路径+库名
在这里插入图片描述
在这里插入图片描述
如下采用原始不含头文件编译方法错误。
在这里插入图片描述
在这里插入图片描述
如下采用ORACLE_HOME换用户时只需要添加该用户.bash_profile中export…进env,不需要改makefile。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面是文件:
在这里插入图片描述
在这里插入图片描述
如下程序只要链接了动态库就需要LD…。
在这里插入图片描述
在这里插入图片描述

2.2 createtable.cpp:setenv/putenv设置环境变量,char补空格,varchar不补空格。确定长度用char快,varchar2(4000)用到几个字符自动分配几个而不是一下给4000字符

#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;
}

在这里插入图片描述
如下trim(c1)去除c1的空格,最后一行不加trim是查不出下面表格。CLOB:结构化数据如文本信息。BLOB:非结构化数据。
在这里插入图片描述

2.3 inserttable.cpp:truncate删除表中全部数据,不产生事务

// 本程序演示向商品表中插入10条记录。
#include "_ooci.h"
// 定义用于操作数据的结构,与表中的字段对应
struct st_GOODS  //结构体值与数据库中表即与createtable.cpp中表对应
{long id;          // 商品编号,用long数据类型对应oracle无小数的numberchar name[31];    // 商品名称,用char对应oracle的varchar2,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符double sal;       // 商品价格,用double数据类型对应oracle有小数的numberchar 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对应上面:1stmt.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;
}

在这里插入图片描述
在这里插入图片描述
注释//conn.commit();则insert后查询无记录,如下开启自动提交。
在这里插入图片描述

2.4 selecttable.cpp:stmt.m_cda.rpc变量保存了SQL执行后影响的记录数

//本程序演示从商品表中查询数据
#include "_ooci.h"
// 定义用于查询数据的结构,与表中的字段对应
struct st_GOODS  //和inserttable.cpp中结构体一样
{long id;          // 商品编号,用long数据类型对应oracle无小数的numberchar name[31];    // 商品名称,用char对应oracle的varchar2,注意,表中字段的长度是30,char定义的长度是31,要留C语言的结束符double sal;       // 商品价格,用double数据类型对应oracle有小数的numberchar 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);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");//id,name,sal,to_char(btime,'yyyy-mm-dd hh24:mi:ss')是输出变量//id>:1 and id<:2是输入变量  // 为SQL语句绑定输入变量的地址stmt.bindin(1,&iminid);stmt.bindin(2,&imaxid);// 为SQL语句绑定输出变量的地址// stgoods.id这些变量在inserttable已经赋过值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,执行一次查询 //inserttable已插入10条记录iminid=1;imaxid=5;//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;}//上面执行完sql语句就得到一个结果集,怎么获取这结果集呢?用next方法while (1){// 先把结构体变量初始化,然后才获取记录memset(&stgoods,0,sizeof(stgoods));// 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败// 在实际应用中,除了0和1403,其它的情况极少出现。if (stmt.next() !=0) break;//每next一次就从结果集里拿一条数据    // 把获取到的记录的值打印出来printf("id=%ld,name=%s,sal=%.02f,btime=%s\n",stgoods.id,stgoods.name,stgoods.sal,stgoods.btime);}printf("本次查询了goods表%ld条记录。\n",stmt.m_cda.rpc);  return 0;
}

2.5 updatetable.cpp:连接数据库,返回值0成功,其它失败,失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中

// 本程序演示更新商品表中数据
#include "_ooci.h"
int main(int argc,char *argv[])
{
//111111111111111111111111111111111111111111111111.数据库连接池connection conn;  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);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);  //1对应上面:1stmt.bindin(2,&iminid);  //2对应上面:2stmt.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");//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;}// 请注意,stmt.m_cda.rpc变量非常重要,它保存了SQL被执行后影响的记录数。printf("本次更新了goods表%ld条记录。\n",stmt.m_cda.rpc);// 提交事务conn.commit();return 0;
}

2.6 deletetable.cpp:删除商品表中数据

#include "_ooci.h"
int main(int argc,char *argv[])
{
//111111111111111111111111111111111111111111111111.数据库连接池connection conn;  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);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到5iminid=1;imaxid=5;//111111111111111111111111111111111111111111113.执行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("本次从goods表中删除了%ld条记录。\n",stmt.m_cda.rpc); conn.commit();return 0;
}

2.7 execplsql.cpp:执行一个PL/SQL过程

在这里插入图片描述

// execplsql.cpp:其中sql:删除全部记录并插入一行
// 在这里说一下我个人的意见,我从不在Oracle数据库中创建PL/SQL过程,也很少使用触发器,原因如下:
// 1、在Oracle数据库中创建PL/SQL过程,程序的调试很麻烦;
// 2、维护工作很麻烦,因为程序员要花时间去了解数据库中的存储过程;
// 3、在封装的oci中,对oracle的操作已经是简单的事情,没必要去折腾存储过程;
// 在oci中也很少用PL/SQL语句,也是因为复杂的PL/SQL调试麻烦。
#include "_ooci.h"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);// 准备删除记录的PL/SQL,不需要判断返回值// 本PL/SQL先删除goods表中的全部记录,再插入一条记录stmt.prepare("\BEGIN\delete from goods;\insert into goods(id,name,sal,btime)\values(:1,'过程商品',55.65,to_date('2018-01-02 13:00:55','yyyy-mm-dd hh24:mi:ss'));\END;");//上面2条sql语句,:1是为了绑定变量,:1换成100就没有下面两行了int id=100;stmt.bindin(1,&id);// 注意,PL/SQL中的每条SQL需要用分号结束,END之后还有一个分号。//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("exec PL/SQL ok.\n");conn.commit();return 0;
}

3.虚表/日期/序列:ntp&hwclock

oracle的虚表dual用来构成select的语法规则,不要当表来看,oracle保证dual里永远只有一条记录,可用它来做如下很多事。
在这里插入图片描述
在这里插入图片描述
如下若是c语言写1/86400就是=0(因为整数除),只有浮点数才能这样运算。oracle中是非常精确的,不用担心精度问题。
在这里插入图片描述
如下sysdate函数返回值可以当成值来用。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
SQL>CREATE SEQUENCE ABC INCREMENT BY 1 START WITH 1 MAXVALUE 9999999999 NOCYCLE NOCACHE;
在这里插入图片描述
如上新建一个序列第一次取当前值是取不到的(提示该序列在此会话中未定义),必须.nextval再.currval取当前值。下面起步为100,步长为5。
在这里插入图片描述
下面给表增加两个字段crttime和keyid(导出数据时用到keyid),下面在crttable.sql中。
在这里插入图片描述
rowid指物理位置。rownum指序号(C语言很少用rownum)。如下第一行select时需要将rownum和rowid写出来查询才能看到,第二行用rowid作为查询或更新的条件最快(区别索引)
在这里插入图片描述
如上每条记录虽然存在数据库里(即表空间,表空间还是数据文件)最后还是存在磁盘上(在磁盘上就有位置),就是/oracle/base/oradata/snorcl11g里的.dbf文件。
在这里插入图片描述

4.索引/视图/链路/同义词:create index/view/link/synonym,distinct

在这里插入图片描述
ddatetime在数据库中是整数
在这里插入图片描述
视图就是访问数据的一个窗口,当成一个表来用,下面为先授权。
在这里插入图片描述
如上可以exit退出,也可直接切换connect scott用户,drop view …
在这里插入图片描述
在这里插入图片描述
视图不占用表空间,在emp将hiredate设置为系统时间,从v_emp查也有效果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面是同义词:数据库对象(表,视图,序列,存储过程,包)的一个别名。实际不可能给shqx和密码给客户,给普通用户如scott给客户并授权。
在这里插入图片描述
在这里插入图片描述
对表使用别名,如下内表是dept,外表是emp。
在这里插入图片描述
distinct关键字,取结果集中的唯一值,去重,如下有很多30,20,10重复。
在这里插入图片描述

5.系统高可用性:12个1T组合,rac

在这里插入图片描述
如下假如oracle数据库在一个服务器上运行,出问题了怎么办?(一般硬件故障)。Oracle三种高可用集群方案:1.RAC,2.Data Guard,3.OGG。如下是RAC技术,可以多个,但一般为两个。有的数据在内存,有的在缓存,2个要进行数据协调很麻烦,所以不是高性能,比单个服务器要慢。
在这里插入图片描述
如下为结合三种集群技术应用。
在这里插入图片描述
RAC有多个节点(上面为两个),应用程序只要做好客户端配置怎么连RAC数据库就行。
在这里插入图片描述

6.txt/xml文件入表:结构体内容

//psurfdata.cpp,txt文件入库封成类
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _psurfdata();
connection conn; //实例化对象,con也叫变量(称呼)
void EXIT(int sig);int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理全国气象站点观测的分钟数据,并保存到数据库的T_SURFDATA表中。\n");printf("这是完善后的程序,未完善的程序在psurfdata_old.cpp中。\n");printf("/htidc/shqx/bin/psurfdata 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/htidc/shqx/bin/psurfdata /data/shqx/sdata/surfdata /log/shqx/psurfdata.log shqx/pwdidc@snorcl11g_198 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");while (true){    
//111111111111111111111111111111111111111111111扫描数据文件存放的目录,只匹配"SURF_ZH_*.txt"// logfile.Write("开始扫描目录。\n");if (Dir.OpenDir(argv[1],"SURF_ZH_*.txt",1000,true,true)==false){logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}//11111111111111111111111111111111111111111111111连接数据库while (true){if (Dir.ReadDir()==false) break;  if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}// logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);//111111111111111111111111111111111111111111111111处理入库if (_psurfdata()==false) {logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); // 断开与数据库的连接sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//11111111111111111111111111111111111111111111111处理入库
bool _psurfdata()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}//1111111111111111111111111111读取文件中的每一行记录,写入数据库的表中CSURFDATA SURFDATA(&conn,&logfile); //上行给m_conn和m_logfile两个指针成员变量赋值初始化也可写成如下两行://SURFDATA.m_conn=&conn;  //con是对象也是变量//SURFDATA.m_logfile=&logfile;char strBuffer[301];                                           while (true){memset(strBuffer,0,sizeof(strBuffer));if (File.Fgets(strBuffer,300,true)==false) break; //从文件中获取一行记录   if (SURFDATA.SplitBuffer(strBuffer)==false) { logfile.Write("%s\n",strBuffer); continue; }// 把用逗号分隔的记录拆分到结构体中long rc=SURFDATA.InsertTable(); //把结构体中的数据更新到T_SURFDATA表中,因为不知道返回哪个sql,所以用long rc =if ( (rc>=3113) && (rc<=3115) ) return false; //只要不是数据库session的错误,程序就继续。if (rc != 0) { logfile.Write("%s\n",strBuffer); continue; }}conn.commit(); //提交事务File.CloseAndRemove(); //关闭文件指针,并删除文件logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",SURFDATA.totalcount,SURFDATA.insertcount,SURFDATA.updatecount,SURFDATA.invalidcount);return true;
}
//psurfdata1.cpp本程序只支持xml文件入库已封装成类,有keyid等字段。
//表加字段,结构体不用,在sqlplus中输入一行创建序列命令,stcode.ini不要最后留空行
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
bool _psurfdata();
connection conn;
void EXIT(int sig);int main(int argc,char *argv[])
{if (argc!=5){printf("\n本程序用于处理全国气象站点观测的分钟数据,并保存到数据库的T_SURFDATA表中。\n");printf("与psurfdata.cpp不同,本程序只支持xml格式。\n");printf("/htidc/shqx/bin/psurfdata1 数据文件存放的目录 日志文件名 数据库连接参数 程序运行时间间隔\n");printf("例如:/htidc/shqx/bin/psurfdata1 /data/shqx/sdata/surfdata /log/shqx/psurfdata1.log shqx/pwdidc@snorcl11g_198 10\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[2]); return -1;}logfile.Write("程序启动。\n");while (true){        
//1111111111111111111111111111111111111111111扫描数据文件存放的目录,匹配"SURF_ZH_*.xml"// logfile.Write("开始扫描目录。\n");if (Dir.OpenDir(argv[1],"SURF_ZH_*.xml",1000,true,true)==false){logfile.Write("Dir.OpenDir(%s) failed.\n",argv[1]); sleep(atoi(argv[4])); continue;}//111111111111111111111111111111111111111111111逐个处理目录中的数据文件while (true){if (Dir.ReadDir()==false) break;//111111111111111111111111111111111111111111111连接数据库if (conn.m_state==0){if (conn.connecttodb(argv[3],"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",argv[3],conn.m_cda.message); break;}// logfile.Write("连接数据库成功。\n");}  logfile.Write("开始处理文件%s...",Dir.m_FileName);//111111111111111111111111111111111111111111111处理入库if (_psurfdata()==false) {logfile.WriteEx("失败。\n"); break;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[4]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//111111111111111111111111111111111111111111111处理入库
bool _psurfdata()
{CFile File;if (File.Open(Dir.m_FullFileName,"r")==false){logfile.Write("(File.Open(%s) failed.\n",Dir.m_FullFileName); return false;}CSURFDATA SURFDATA(&conn,&logfile);char strBuffer[301];while (true){memset(strBuffer,0,sizeof(strBuffer));if (File.FFGETS(strBuffer,300,"<endl/>")==false) break;// logfile.Write("str=%s=\n",strBuffer);// logfile.Write("%s\n",strBuffer);    if (SURFDATA.SplitBuffer1(strBuffer)==false) { logfile.Write("%s\n",strBuffer); continue; }long rc=SURFDATA.InsertTable();    if ( (rc>=3113) && (rc<=3115) ) return false; // 只要不是数据库session的错误,程序就继续。if (rc != 0) { logfile.Write("%s\n",strBuffer); continue; }}conn.commit();  File.CloseAndRemove();  //关闭文件指针,并删除文件logfile.WriteEx("成功(total=%d,insert=%d,update=%d,invalid=%d)。\n",SURFDATA.totalcount,SURFDATA.insertcount,SURFDATA.updatecount,SURFDATA.invalidcount);return true;
}
//_shqx.h
#ifndef _SHQX_H
#define _SHQX_H
#include "_public.h"
#include "_ooci.h"
struct st_stcode  //全国气象站点参数数据结构
{char provname[31];   // 省名称char obtid[11];      // 站点代码char cityname[31];   // 城市名double lat;          // 纬度double lon;          // 经度double height;       // 海拔高度
};
struct st_surfdata  //全国气象站点分钟观测数据结构
{char obtid[11];      // 站点代码char ddatetime[21];  // 数据时间:格式yyyy-mm-dd hh:mi:ss。int  t;              // 气温:单位,0.1摄氏度int  p;              // 气压:0.1百帕int  u;              // 相对湿度,0-100之间的值。int  wd;             // 风向,0-360之间的值。int  wf;             // 风速:单位0.1m/sint  r;              // 降雨量:0.1mmint  vis;            // 能见度:0.1米
};
struct st_signallog  //分区信号数据结构
{char obtid[11];char ddatetime[20];char signalname[2];char signalcolor[2];
};//111111111111111111111111111111111111111111111111CSURFDATA类
class CSURFDATA
{
public:int totalcount,insertcount,updatecount,invalidcount;  // 记录总数据、插入数、更新数、无效记录数。struct st_surfdata m_stsurfdata;CSURFDATA(connection *conn,CLogFile *logfile); //在构造函数里传进参数~CSURFDATA();void initdata();  // 数据初始化connection *m_conn; //在类里操作数据库需要一个指针,m_conn,m_logfile这两个成员需要给它们赋值CLogFile   *m_logfile; //在类里写日志,m_logfile->,类里不能再类实例化,所以定义为指针int iccount; //不能定义到成员函数里值会变sqlstatement stmtsel,stmtins,stmtupt;// 把用逗号分隔的记录拆分到m_stsurfdata结构中。bool SplitBuffer(const char *strBuffer);  // 把xml格式的记录拆分到m_stsurfdata结构中。bool SplitBuffer1(const char *strBuffer);// 把m_stsurfdata结构中的值更新到T_SURFDATA表中。long InsertTable();
};//1111111111111111111111111111111111111111111111CSIGNALLOG类
class CSIGNALLOG
{
public:int totalcount,insertcount,updatecount,invalidcount;  // 记录总数据、插入数、更新数、无效记录数。struct st_signallog m_stsignallog;vector<struct st_signallog> vsignallog;   // 容器存放一个文件的全部记录CSIGNALLOG(connection *conn,CLogFile *logfile);~CSIGNALLOG();void initdata();  // 数据初始化connection *m_conn;CLogFile   *m_logfile;int iccount;sqlstatement stmtsel,stmtins,stmtupt; bool SplitBuffer(const char *strBuffer);  // 把记录拆分到vsignallog容器中。  long InsertTable(); // 把vsignallog容器中的值更新到T_SIGNALDATA表中。
};//11111111111111111111111111111111111111111把非结构化数据文件写入oracle数据库的表中
int FileToTable(connection *in_conn,CLogFile *in_logfile,char *in_tname,char *in_filename,char *in_ddatetime);
#endif
//_shqx.cpp
#include "_shqx.h"
//11111111111111111111111111111111111111111111111111111CSURFDATA类
CSURFDATA::CSURFDATA(connection *conn,CLogFile *logfile)
{initdata();        // 构造函数里传入两个指针变量并赋初值m_conn=conn; m_logfile=logfile;  // 所以调用CSURFDATA(&conn,&logfile);就能完成初始化
}
void CSURFDATA::initdata()
{totalcount=insertcount=updatecount=invalidcount=0;m_conn=0; m_logfile=0;memset(&m_stsurfdata,0,sizeof(struct st_surfdata));
}
CSURFDATA::~CSURFDATA()
{
}bool CSURFDATA::SplitBuffer(const char *strBuffer) //把用逗号分隔的记录拆分到m_stsurfdata结构中
{ totalcount++;memset(&m_stsurfdata,0,sizeof(struct st_surfdata));CCmdStr CmdStr;CmdStr.SplitToCmd(strBuffer,",",true);if (CmdStr.CmdCount()!=9) { invalidcount++; return false; }CmdStr.GetValue(0,m_stsurfdata.obtid,5);      // 站点代码CmdStr.GetValue(1,m_stsurfdata.ddatetime,19); // 数据时间:格式yyyy-mm-dd hh:mi:ss。double dtmp=0;CmdStr.GetValue(2,&dtmp); m_stsurfdata.t=(int)(dtmp*10);  // 气温:单位,0.1摄氏度CmdStr.GetValue(3,&dtmp); m_stsurfdata.p=(int)(dtmp*10);  // 气压:0.1百帕CmdStr.GetValue(4,&m_stsurfdata.u);  // 相对湿度,0-100之间的值。CmdStr.GetValue(5,&m_stsurfdata.wd); // 风向,0-360之间的值。CmdStr.GetValue(6,&dtmp); m_stsurfdata.wf=(int)(dtmp*10);  // 风速:单位0.1m/sCmdStr.GetValue(7,&dtmp); m_stsurfdata.r=(int)(dtmp*10);   // 降雨量:0.1mmCmdStr.GetValue(8,&dtmp); m_stsurfdata.vis=(int)(dtmp*10); // 能见度:0.1米return true;
}bool CSURFDATA::SplitBuffer1(const char *strBuffer) //把xml格式的记录拆分到m_stsurfdata结构中
{totalcount++;memset(&m_stsurfdata,0,sizeof(struct st_surfdata));GetXMLBuffer(strBuffer,"obtid",m_stsurfdata.obtid,5);      // 站点代码GetXMLBuffer(strBuffer,"ddatetime",m_stsurfdata.ddatetime,19); // 数据时间:格式yyyy-mm-dd hh:mi:ss。double dtmp=0;GetXMLBuffer(strBuffer,"t",&dtmp); m_stsurfdata.t=(int)(dtmp*10);  // 气温:单位,0.1摄氏度GetXMLBuffer(strBuffer,"p",&dtmp); m_stsurfdata.p=(int)(dtmp*10);  // 气压:0.1百帕GetXMLBuffer(strBuffer,"u",&m_stsurfdata.u);  // 相对湿度,0-100之间的值。GetXMLBuffer(strBuffer,"wd",&m_stsurfdata.wd);  // 风向,0-360之间的值。GetXMLBuffer(strBuffer,"wf",&dtmp); m_stsurfdata.wf=(int)(dtmp*10);  // 风速:单位0.1m/sGetXMLBuffer(strBuffer,"r",&dtmp); m_stsurfdata.r=(int)(dtmp*10);   // 降雨量:0.1mmGetXMLBuffer(strBuffer,"vis",&dtmp);  m_stsurfdata.vis=(int)(dtmp*10); // 能见度:0.1米return true;
}long CSURFDATA::InsertTable() //把m_stsurfdata结构中的值更新到T_SURFDATA表中
{if (stmtsel.m_state==0){stmtsel.connect(m_conn);stmtsel.prepare("select count(*) from T_SURFDATA where obtid=:1 and ddatetime=to_date(:2,'yyyy-mm-dd hh24:mi:ss')");stmtsel.bindin( 1, m_stsurfdata.obtid,5);stmtsel.bindin( 2, m_stsurfdata.ddatetime,19);stmtsel.bindout(1,&iccount);}if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_SURFDATA(obtid,ddatetime,t,p,u,wd,wf,r,vis,crttime,keyid) values(:1,to_date(:2,'yyyy-mm-dd hh24:mi:ss'),:3,:4,:5,:6,:7,:8,:9,sysdate,SEQ_SURFDATA.nextval)");stmtins.bindin( 1, m_stsurfdata.obtid,5);stmtins.bindin( 2, m_stsurfdata.ddatetime,19);stmtins.bindin( 3,&m_stsurfdata.t);stmtins.bindin( 4,&m_stsurfdata.p);stmtins.bindin( 5,&m_stsurfdata.u);stmtins.bindin( 6,&m_stsurfdata.wd);stmtins.bindin( 7,&m_stsurfdata.wf);stmtins.bindin( 8,&m_stsurfdata.r);stmtins.bindin( 9,&m_stsurfdata.vis);}if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_SURFDATA set t=:1,p=:2,u=:3,wd=:4,wf=:5,r=:6,vis=:7 where obtid=:8 and ddatetime=to_date(:2,'yyyy-mm-dd hh24:mi:ss')");stmtupt.bindin( 1,&m_stsurfdata.t);stmtupt.bindin( 2,&m_stsurfdata.p);stmtupt.bindin( 3,&m_stsurfdata.u);stmtupt.bindin( 4,&m_stsurfdata.wd);stmtupt.bindin( 5,&m_stsurfdata.wf);stmtupt.bindin( 6,&m_stsurfdata.r);stmtupt.bindin( 7,&m_stsurfdata.vis);stmtupt.bindin( 8, m_stsurfdata.obtid,5);stmtupt.bindin( 9, m_stsurfdata.ddatetime,19);}if (stmtsel.execute() != 0){invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();if (iccount>0) {if (stmtupt.execute() != 0)   //执行更新的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{   if (stmtins.execute() != 0)  // 执行插入的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}return 0;
}//1111111111111111111111111111111111111111111111111111111111111CSIGNALLOG类
CSIGNALLOG::CSIGNALLOG(connection *conn,CLogFile *logfile)
{initdata();m_conn=conn; m_logfile=logfile;
}
void CSIGNALLOG::initdata()
{totalcount=insertcount=updatecount=invalidcount=0;m_conn=0; m_logfile=0;memset(&m_stsignallog,0,sizeof(struct st_signallog));vsignallog.clear();
}
CSIGNALLOG::~CSIGNALLOG()
{
}bool CSIGNALLOG::SplitBuffer(const char *strBuffer) //把记录拆分到vsignallog容器中
{vsignallog.clear();memset(&m_stsignallog,0,sizeof(struct st_signallog));CCmdStr CmdStr;  CmdStr.SplitToCmd(strBuffer," ",true);if (CmdStr.CmdCount()<3) { invalidcount++; return false; }CmdStr.GetValue(0,m_stsignallog.ddatetime,12); //数据时间:格式yyyymmddhh24mistrcat(m_stsignallog.ddatetime,"00");AddTime(m_stsignallog.ddatetime,m_stsignallog.ddatetime,8*60*60,"yyyy-mm-dd hh24:mi:ss");CmdStr.GetValue(1,m_stsignallog.obtid,4);   //站点代码char strtemp[11];for (int ii=3;ii<=CmdStr.CmdCount();ii++){ // 201809142353 GWTE A3000 ....= memset(strtemp,0,sizeof(strtemp));CmdStr.GetValue(ii-1,strtemp,5);  // m_stsignallog.signalname[0]表示字符串中第一个字符m_stsignallog.signalname[0]=strtemp[0]; //strtemp[0]就是Am_stsignallog.signalcolor[0]=strtemp[1]; //strtemp[1]就是3vsignallog.push_back(m_stsignallog);totalcount++;}return true;
}long CSIGNALLOG::InsertTable()  //把vsignallog容器中的值更新到T_SIGNALDATA表中
{ //可能会返回stmtupt.m_cda.rc,所以用longif (stmtsel.m_state==0){stmtsel.connect(m_conn);// 如下这个表的主键有三个字段stmtsel.prepare("select count(*) from T_SIGNALLOG where obtid=:1 and ddatetime=to_date(:2,'yyyy-mm-dd hh24:mi:ss') and signalname=:3");stmtsel.bindin( 1, m_stsignallog.obtid,4);stmtsel.bindin( 2, m_stsignallog.ddatetime,19);stmtsel.bindin( 3, m_stsignallog.signalname,1);stmtsel.bindout(1,&iccount);}if (stmtins.m_state==0){stmtins.connect(m_conn);stmtins.prepare("insert into T_SIGNALLOG(obtid,ddatetime,signalname,signalcolor,crttime,keyid) values(:1,to_date(:2,'yyyy-mm-dd hh24:mi:ss'),:3,:4,sysdate,SEQ_SIGNALLOG.nextval)");stmtins.bindin( 1, m_stsignallog.obtid,4);stmtins.bindin( 2, m_stsignallog.ddatetime,19);stmtins.bindin( 3, m_stsignallog.signalname,1);stmtins.bindin( 4, m_stsignallog.signalcolor,1);}if (stmtupt.m_state==0){stmtupt.connect(m_conn);stmtupt.prepare("update T_SIGNALLOG set signalcolor=:1 where obtid=:2 and ddatetime=to_date(:3,'yyyy-mm-dd hh24:mi:ss') and signalname=:4");stmtupt.bindin( 1, m_stsignallog.signalcolor,1);stmtupt.bindin( 2, m_stsignallog.obtid,4);stmtupt.bindin( 3, m_stsignallog.ddatetime,19);stmtupt.bindin( 4, m_stsignallog.signalname,1);}for (int ii=0;ii<vsignallog.size();ii++){ //把容器里的值拷出来memcpy(&m_stsignallog,&vsignallog[ii],sizeof(struct st_signallog));m_logfile->Write("%s,%s,%s,%s\n",m_stsignallog.obtid,m_stsignallog.ddatetime,m_stsignallog.signalname,m_stsignallog.signalcolor);if (stmtsel.execute() != 0){invalidcount++; m_logfile->Write("stmtsel.execute() failed.\n%s\n%s\n",stmtsel.m_sql,stmtsel.m_cda.message); return stmtsel.m_cda.rc;}  iccount=0;stmtsel.next();  if (iccount>0) {    if (stmtupt.execute() != 0)   //执行更新的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtupt.execute() failed.\n%s\n%s\n",stmtupt.m_sql,stmtupt.m_cda.message);return stmtupt.m_cda.rc;}updatecount++;}else{      if (stmtins.execute() != 0)  //执行插入的SQL语句,一定要判断返回值,0-成功,其它-失败。{invalidcount++; m_logfile->Write("stmtins.execute() failed.\n%s\n%s\n",stmtins.m_sql,stmtins.m_cda.message);return stmtins.m_cda.rc;}insertcount++;}}return 0;
}//11111111111111111111111111111111111111111111111把非结构化数据文件写入oracle数据库的表中
int FileToTable(connection *in_conn,CLogFile *in_logfile,char *in_tname,char *in_filename,char *in_ddatetime)
{sqlstatement stmt(in_conn);  int icount=0;  //判断文件记录在表中是否已存在stmt.prepare("select count(*) from %s where filename=:1",in_tname);stmt.bindin(1,in_filename,300);stmt.bindout(1,&icount);if (stmt.execute() != 0){in_logfile->Write("FileToTable() failed.%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return stmt.m_cda.rc;}stmt.next();  if (icount>0) return 0;  //如果记录已存在,直接返回0-成功。  //11111111111111111111111111111111111111111111111111111111111111111int ifilesize=FileSize(in_filename);  //把文件信息插入表中。stmt.prepare("\insert into %s(filename,ddatetime,filesize,filecontent,crttime,keyid)\values(:1,to_date(:2,'yyyymmddhh24miss'),:3,empty_blob(),sysdate,SEQ_%s.nextval)",\in_tname,in_tname+2);  stmt.bindin(1,in_filename,300); //empty_blob()可以换成null试试,文件内容可以不弄到blob字段stmt.bindin(2,in_ddatetime,14);stmt.bindin(3,&ifilesize);  if (stmt.execute() != 0){in_logfile->Write("FileToTable() failed.%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return stmt.m_cda.rc;}    //111111111111111111111111111111111111111111111111111111111111111stmt.prepare("select filecontent from %s where filename=:1 for update",in_tname);stmt.bindin(1,in_filename,300);   //把文件内容更新到BLOB字段中。stmt.bindblob();if (stmt.execute() != 0){in_logfile->Write("FileToTable() failed.%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return stmt.m_cda.rc;}    if (stmt.next() != 0) return -1; //获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败  if (stmt.filetolob((char *)in_filename) != 0) { //把磁盘文件pic_in.jpg的内容写入BLOB字段,一定要判断返回值,0-成功,其它-失败。in_logfile->Write("FileToTable() stmt.filetolob() failed.\n%s\n",stmt.m_cda.message); return -1;} in_conn->commit(); //图片数据大,一个文件提交一次return 0;
}

创建新用户并指定该用户缺省表空间为users,vi creuser.sql。

--把数据库用户允许错误重试的次数改为不限制
alter profile DEFAULT limit FAILED_LOGIN_ATTEMPTS UNLIMITED;
alter profile DEFAULT limit PASSWORD_LIFE_TIME  UNLIMITED;-- 上海气象数据中心的主用户,shqx为用户名,pwdidc为密码,default tablespace users默认user表空间
-- drop user shqx cascade;
create user shqx profile default identified by pwdidc default tablespace users account unlock;
grant connect to shqx;
grant dba to shqx;
exit;

下面是以超级用户登录,/ 指不用任何密码,不能远程登录只能登录本机且装有数据库。
在这里插入图片描述

7.站点参数建表入表/PowerDesigner/主外键:多表查询

vi crttable.sql,T_OBTCODE这个表没必要创建索引,因为数据量很少。

drop table T_OBTCODE;
create table T_OBTCODE
(obtid      char(5),cityname   varchar2(30),provname   varchar2(30),lat        number(5,2),lon        number(5,2),height     number(8,2),rsts       number(1),    --状态:1-启用,2-禁用,3-故障primary key(obtid)
);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如下图整列(列操作)插入',1);,技巧:alt+shift+鼠标拖动右边滚条到最低+鼠标点击最低。如下取消勾选全词匹配。
在这里插入图片描述
在这里插入图片描述
vi T_OBTCODE.sql将上面列操作实现的sql全部复制进去。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
vi T_OBTCODE.sql改完后。
在这里插入图片描述
PowerDesigner安装链接:https://pan.baidu.com/s/1TR5tT6qh7G4CVPDFxZ7_wg 提取码:vx9m 。
在这里插入图片描述
将上面汉化…文件夹里文件全复制替换到下面安装目录中(可改变安装目录)。
在这里插入图片描述
上海气象.pdm文件:链接:https://pan.baidu.com/s/1zkzGDQuggwZhd1oNobeVqQ 提取码:0ad6 。
在这里插入图片描述
P:主键,F:外键,M:勾上不允许为空。
在这里插入图片描述
1.下面为主键命名,主键在Columns里p字段已指定。
在这里插入图片描述
如下是主键的另一种写法。
在这里插入图片描述
2.下面为创建索引
在这里插入图片描述
在这里插入图片描述
3.下面为创建表空间,如下将表存入名为USERS的表空间。
在这里插入图片描述
如下将索引存入名为INDEXS表空间。
在这里插入图片描述
如下主键就是索引也有这些参数也扔入INDEXS表空间。
在这里插入图片描述
4.字段值附上约束条件,如果复制其他表记得删除字段值约束条件
在这里插入图片描述
5.如下U是unique index,记录序号即keyid是唯一约束,第三行是数据时间。
在这里插入图片描述
下面是创建序列。
在这里插入图片描述
ctrl+G生成.sql文件,注意主键名不要重复,双引号替换为空。复制刚生成的.sql文件内容到crttable.sql中,执行如下命令必须其他窗口SQL>exit。
在这里插入图片描述

8.数据交换:数据导出为文件,数据文件推送

在这里插入图片描述

// exptables.cpp
#include "_public.h"
#include "_ooci.h"
struct st_arg // 主程序的参数
{char connstr[101];char charset[51];char tname[51];char cols[1001];char fieldname[1001];char fieldlen[501];int  exptype;char andstr[501];char bname[51];char ename[51];char taskname[51];char exppath[301];int  timetvl;
} starg;
CLogFile logfile;
connection conn;
bool _exptables();  // 本程序的业务流程主函数
void EXIT(int sig);
vector<string> vfieldname; // 存放拆分fieldname后的容器
vector<int>    vfieldlen;  // 存放拆分fieldlen后的容器
int maxfieldlen;           // 存放fieldlen的最大值
void SplitFields();        // 拆分fieldname和fieldlen
void _help(char *argv[]); // 显示程序的帮助
long maxkeyid;   // 已导出数据的最大的keyid
bool LoadMaxKeyid(); // 从系统参数T_SYSARG表中加载已导出数据的最大的keyid
bool UptMaxKeyid();  // 更新系统参数T_SYSARG表中已导出数据的最大的keyid  
bool _xmltoarg(char *strxmlbuffer); // 把xml解析到参数starg结构中int main(int argc,char *argv[])
{if (argc!=3) { _help(argv); return -1; }CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[1],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[1]); return -1;}  if (_xmltoarg(argv[2])==false) return -1; // 把xml解析到参数starg结构中while (true){ // 连接数据库 //放while (true)外面连耗资源    if (conn.connecttodb(starg.connstr,starg.charset) != 0){logfile.Write("connect database %s failed.\n",starg.connstr); sleep(starg.timetvl); continue;}// logfile.Write("export table %s.\n",starg.tname);if (_exptables() == false) logfile.Write("export tables failed.\n"); //导出数据的主函数conn.disconnect();   // 断开与数据库的连接sleep(starg.timetvl);}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//1111111111111111111111111111111111111111111111111111111111111111111111
void _help(char *argv[])
{printf("\n");printf("Using:/htidc/public/bin/exptables logfilename xmlbuffer\n\n");printf("增量导出示例:\n");printf("/htidc/public/bin/exptables /log/shqx/exptables_surfdata_for_hb.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_SURFDATA</tname><cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols><fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname><fieldlen>5,14,8,8,8,8,8,8,8</fieldlen><exptype>1</exptype><andstr> and obtid in ('59293','50745')</andstr><bname>SURFDATA_</bname><ename>_for_hb</ename><taskname>SURFDATA_FOR_HB</taskname><exppath>/data/shqx/exp/tohb</exppath><timetvl>30</timetvl>\"\n\n");printf("全量导出示例:\n");printf("/htidc/public/bin/exptables /log/shqx/exptables_obtcode_for_hb.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_OBTCODE</tname><cols>obtid,obtname,provname,lat,lon,height</cols><fieldname>obtid,obtname,provname,lat,lon,height</fieldname><fieldlen>5,30,30,8,8,8</fieldlen><exptype>2</exptype><andstr> and rsts=1 and obtid in ('59293','50745')</andstr><bname>OBTCODE_</bname><ename>_for_hb</ename><exppath>/data/shqx/exp/tohb</exppath><timetvl>300</timetvl>\"\n\n");printf("本程序是数据中心的公共功能模块,从数据库的表中导出数据生成xml文件,用于数据交换。\n");printf("logfilename是本程序运行的日志文件。\n");printf("xmlbuffer为文件传输的参数,如下:\n");printf("数据库的连接参数 <connstr>shqx/pwdidc@snorcl11g_198</connstr>\n");printf("数据库的字符集 <charset>Simplified Chinese_China.ZHS16GBK</charset> 这个参数要与数据源数据库保持>一致,否则会出现中文乱码的情况。\n");printf("待导出数据的表名 <tname>T_SURFDATA</tname>\n");printf("需要导出字段的列表 <cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols> 可以采用函数。\n");printf("导出字段的别名列表 <fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname> 必须与cols一一对应。\n");printf("导出字段的长度列表 <fieldlen>5,14,8,8,8,8,8,8,8</fieldlen> 必须与cols一一对应。\n");printf("导出数据的方式 <exptype>1</exptype> 1-增量导出;2-全量导出,如果是增量导出,要求表一定要有keyid字段。\n");printf("导出数据的附加条件 <andstr> and obtid in ('59293','50745')</andstr> 注意,关键字and不能少。\n");printf("导出文件的命名的前部分 <bname>SURFDATA_</bname>\n");printf("导出文件的命名的后部分 <ename>_for_hb</ename>\n");printf("导出任务的命名 <taskname>SURFDATA_FOR_HB</taskname> 当exptype=1时该参数有效。\n");printf("导出文件存放的目录 <exppath>/data/shqx/exp/tohb</exppath>\n");printf("导出数据的时间间隔 <timetvl>30</timetvl> 单位:秒,建议大于10。\n");printf("以上参数,除了taskname和andstr,其它字段都不允许为空。\n\n\n");
}bool _xmltoarg(char *strxmlbuffer)
{memset(&starg,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer,"connstr",starg.connstr);if (strlen(starg.connstr)==0) { logfile.Write("connstr is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"charset",starg.charset);if (strlen(starg.charset)==0) { logfile.Write("charset is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"tname",starg.tname);if (strlen(starg.tname)==0) { logfile.Write("tname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"cols",starg.cols);if (strlen(starg.cols)==0) { logfile.Write("cols is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"fieldname",starg.fieldname);if (strlen(starg.fieldname)==0) { logfile.Write("fieldname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"fieldlen",starg.fieldlen);if (strlen(starg.fieldlen)==0) { logfile.Write("fieldlen is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"exptype",&starg.exptype);if ( (starg.exptype!=1) && (starg.exptype!=2) ) { logfile.Write("exptype is not in (1,2).\n"); return false; }GetXMLBuffer(strxmlbuffer,"andstr",starg.andstr);if (strlen(starg.andstr)==0) { logfile.Write("andstr is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"bname",starg.bname);if (strlen(starg.bname)==0) { logfile.Write("bname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"ename",starg.ename);if (strlen(starg.ename)==0) { logfile.Write("ename is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"taskname",starg.taskname);if ( (starg.exptype==1) && (strlen(starg.taskname)==0) ) { logfile.Write("taskname is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"exppath",starg.exppath);if (strlen(starg.exppath)==0) { logfile.Write("exppath is null.\n"); return false; }GetXMLBuffer(strxmlbuffer,"timetvl",&starg.timetvl);if (starg.timetvl==0) { logfile.Write("timetvl is null.\n"); return false; }// 拆分fieldname和fieldlenSplitFields();// 判断fieldname和fieldlen中元素的个数一定要相同if (vfieldname.size() != vfieldlen.size() ) { logfile.Write("fieldname和fieldlen的元素个数不同。.\n"); return false; }return true;
}//111111111111111111111111111111111111111本程序的业务流程主函数
bool _exptables()
{// 从系统参数T_SYSARG表中加载已导出数据的最大的keyidif (LoadMaxKeyid()==false) { logfile.Write("LoadMaxKeyid() failed.\n"); return false; } // 生成导出数据的SQL语句char strsql[4096]; char fieldvalue[vfieldname.size()][maxfieldlen+1]; // 输出变量定义为一个二维数组//第一维vfieldname.size()字段个数(限制fieldvalue外个数),第二维maxfieldlen+1字段长度(限制fieldvalue内个数),+1是最后一个空字符结尾符//导出数据的结果不管是字符串,整数还是浮点数都用字符串存放memset(strsql,0,sizeof(strsql));if (starg.exptype==1)  //增量导出, order by keyid排完序后数据好导入sprintf(strsql,"select %s,keyid from %s where 1=1 and keyid>%ld %s order by keyid",starg.cols,starg.tname,maxkeyid,starg.andstr);else //全量导出不需要keyidsprintf(strsql,"select %s from %s where 1=1 %s",starg.cols,starg.tname,starg.andstr);sqlstatement stmt(&conn);stmt.prepare(strsql);  for (int ii=0;ii<vfieldname.size();ii++){stmt.bindout(ii+1,fieldvalue[ii],vfieldlen[ii]); //绑定变量从1开始算}// 如果是增量导出,还要绑定keyid字段if (starg.exptype==1) stmt.bindout(vfieldname.size()+1,&maxkeyid);      if (stmt.execute() != 0)  // 执行导出数据的SQL{logfile.Write("select %s failed.\n%s\n%s\n",starg.tname,stmt.m_cda.message,stmt.m_sql); return false;}int  iFileSeq=1;   // 待生成文件的序号,临时变量,文件名不会重复了char strFileName[301],strLocalTime[21];CFile File;while (true){   // 如果在循环外面打开文件,stmt.next若是没记录又要删除文件memset(fieldvalue,0,sizeof(fieldvalue));   if (stmt.next() !=0) break;    if (File.IsOpened()==false)  // 把数据写入文件{memset(strLocalTime,0,sizeof(strLocalTime));LocalTime(strLocalTime,"yyyymmddhh24miss");memset(strFileName,0,sizeof(strFileName));sprintf(strFileName,"%s/%s%s%s_%d.xml",starg.exppath,starg.bname,strLocalTime,starg.ename,iFileSeq++);if (File.OpenForRename(strFileName,"w")==false){logfile.Write("File.OpenForRename(%s) failed.\n",strFileName); return false;}File.Fprintf("<data>\n");}for (int ii=0;ii<vfieldname.size();ii++){ //数据一个字段一个字段写入xml文件中File.Fprintf("<%s>%s</%s>",vfieldname[ii].c_str(),fieldvalue[ii],vfieldname[ii].c_str());}File.Fprintf("<endl/>\n");//111111111111111111111111111111111111111111111111111111111111if (stmt.m_cda.rpc%1000==0)  //每写入1000行关闭文件{File.Fprintf("</data>\n");if (File.CloseAndRename()==false){logfile.Write("File.CloseAndRename(%s) failed.\n",strFileName); return false;}// 更新系统参数T_SYSARG表中已导出数据的最大的keyidif (UptMaxKeyid()==false) { logfile.Write("UptMaxKeyid() failed.\n"); return false; }logfile.Write("create file %s ok.\n",strFileName);}}//1111111111111111111111111111111111111111111111111111111111if (File.IsOpened()==true) //不够1000条的写入一个文件{File.Fprintf("</data>\n");if (File.CloseAndRename()==false){logfile.Write("File.CloseAndRename(%s) failed.\n",strFileName); return false;}// 更新系统参数T_SYSARG表中已导出数据的最大的keyidif (UptMaxKeyid()==false) { logfile.Write("UptMaxKeyid() failed.\n"); return false; }logfile.Write("create file %s ok.\n",strFileName);}if (stmt.m_cda.rpc>0) logfile.Write("本次导出了%d条记录。\n",stmt.m_cda.rpc);return true;
}//1111111111111111111111111111111111111111111111111111
void SplitFields() //拆分fieldname和fieldlen
{vfieldname.clear(); vfieldlen.clear(); maxfieldlen=0;  CCmdStr CmdStr;CmdStr.SplitToCmd(starg.fieldname,",");vfieldname.swap(CmdStr.m_vCmdStr);int ifieldlen=0;CmdStr.SplitToCmd(starg.fieldlen,",");for (int ii=0;ii<CmdStr.CmdCount();ii++){  CmdStr.GetValue(ii,&ifieldlen); //maxfieldlen一开始为0if (ifieldlen>maxfieldlen) maxfieldlen=ifieldlen; //得到fieldlen的最大值maxfieldlenvfieldlen.push_back(ifieldlen);}
}//111111111111111111111111111111111从系统参数T_SYSARG表中加载已导出数据的最大的keyid
bool LoadMaxKeyid() //实现增量采集必须把每次导出数据的keyid保存起来,所以采用一个T_SYSARG参数表
{   //taskname作为参数代码argcodeif (starg.exptype!=1) return true; //只有增量导出才需要加载/更新系统参数表sqlstatement stmt(&conn);stmt.prepare("select argvalue from T_SYSARG where argcode=:1");stmt.bindin(1,starg.taskname,50);stmt.bindout(1,&maxkeyid);if (stmt.execute() != 0){logfile.Write("select T_SYSARG failed.\n%s\n%s\n",stmt.m_cda.message,stmt.m_sql); return false;}// 如果记录不存在,插入一新记录。if (stmt.next() != 0){ //一直只有一条记录:SURFDATA_FOR_HB,SURFDATA_FOR_HB,0stmt.prepare("insert into T_SYSARG(argcode,argname,argvalue) values(:1,:2,0)");stmt.bindin(1,starg.taskname,50);stmt.bindin(2,starg.taskname,50);stmt.execute();conn.commit();}// logfile.Write("maxkeyid=%d\n",maxkeyid);return true;
}//1111111111111111111111111111111111更新系统参数T_SYSARG表中已导出数据的最大的keyid
bool UptMaxKeyid() //导出前加载,导出后更新
{if (starg.exptype!=1) return true;sqlstatement stmt(&conn);stmt.prepare("update T_SYSARG set argvalue=:1 where argcode=:2");stmt.bindin(1,&maxkeyid);stmt.bindin(2,starg.taskname,50);if (stmt.execute() != 0){logfile.Write("select T_SYSARG failed.\n%s\n%s\n",stmt.m_cda.message,stmt.m_sql); return false;}conn.commit();return true;
}

下面为全量导出站点参数表。
在这里插入图片描述
在这里插入图片描述
vi …1.xml,只导出了2条记录一个文件。
在这里插入图片描述
程序在后台跑,有新图就拿下来,wgetclient将网页内容全弄下来,搞清图片命名规律进行解析。

//wgetclient.cpp
#include "_public.h"
void EXIT(int sig);
CLogFile       logfile;
int main(int argc, char *argv[])
{if(argc!=6){printf("Usage:%s weburl tmpfilename outputfilename logfilename charset\n",argv[0]); printf("本程序用于获取WEB网页的内容。\n");printf("weburl 网页WEB的地址。\n");printf("tmpfilename 获取到的网页的内容存放的全路径的临时文件名,该文件可能是utf-8或其它编码。\n");printf("outputfilename 最终的输出文件全路径文件名,该文件是gb18030编码,注意tmpfilename被转换为outputfilename后,tmpfilename文件被自动删除。\n");printf("logfilename 本程序的运行产生的日志文件名。\n");printf("charset 网页的字符集,如utf-8\n\n");exit(1);}// 关闭全部的信号和输入输出// 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程// 但请不要用 "kill -9 +进程号" 强行终止CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[4],"a+") == false){printf("logfile.Open(%s) failed.\n",argv[4]); return -1;}MKDIR(argv[2],true); MKDIR(argv[3],true);char strweburl[3001];memset(strweburl,0,sizeof(strweburl));strncpy(strweburl,argv[1],3000);char strcmd[3024];memset(strcmd,0,sizeof(strcmd));snprintf(strcmd,3000,"/usr/bin/wget -c -q -O %s \"%s\" 1>>/dev/null 2>>/dev/null",argv[2],strweburl);system(strcmd);logfile.Write("%s\n",strcmd);char strfilenametmp[301];memset(strfilenametmp,0,sizeof(strfilenametmp));snprintf(strfilenametmp,300,"%s.tmp",argv[3]);// 把获取到的网页转换为中文memset(strcmd,0,sizeof(strcmd));snprintf(strcmd,256,"iconv -c -f %s -t gb18030 %s -o %s",argv[5],argv[2],strfilenametmp);system(strcmd);logfile.Write("%s\n",strcmd);REMOVE(argv[2]);   // 删除临时文件 RENAME(strfilenametmp,argv[3]);return 0;
}void EXIT(int sig)
{if (sig > 0) signal(sig,SIG_IGN);logfile.Write("catching the signal(%d).\n",sig);logfile.Write("wgetclient exit.\n");exit(0);
}

在这里插入图片描述

//wgetrain24.cpp
#include "_public.h"
void EXIT(int sig);
CLogFile       logfile;
bool GetURL(char *strBuffer,char *strURL,char *strFileName);
int main(int argc, char *argv[])
{if(argc!=4){printf("Usage:%s logfilename tmpfilename outputfilename\n",argv[0]); printf("Sample:./wgetrain24 /log/shqx/wgetrain24.log /data/wgettmp /data/wfile/zhrain24\n\n");printf("本程序用于从中国天气网获取逐小时降雨量实况图。\n");printf("中国天气网的url是http://products.weather.com.cn/product/Index/index/procode/JC_JSL_ZH.shtml\n");printf("如果中国天气网的url改变,程序也在做改动。\n");printf("logfilename 本程序的运行产生的日志文件名。\n");printf("tmpfilename 本程序运行产生的临时文件存放的目录。\n");printf("获取逐小时降雨量实况图存放的目录。\n\n");exit(1);}CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[1],"a+") == false){printf("logfile.Open(%s) failed.\n",argv[1]); return -1;}MKDIR(argv[2],false); MKDIR(argv[3],false);while (true){    char strwgetclient[2001];  // 调用wgetclient获取网页内容memset(strwgetclient,0,sizeof(strwgetclient));snprintf(strwgetclient,2000,"/htidc/public/bin/wgetclient \"http://products.weather.com.cn/product/Index/index/procode/JC_JSL_ZH.shtml\" %s/wgetclient_%d.tmp  %s/wgetclient_%d.html %s/wgetclient.log utf-8",argv[2],getpid(),argv[2],getpid(),argv[2]);system(strwgetclient);// logfile.Write("%s\n",strwgetclient);// 打开网页内容文件char stroutputfile[301];memset(stroutputfile,0,sizeof(stroutputfile));snprintf(stroutputfile,300,"%s/wgetclient_%d.html",argv[2],getpid());CFile File;if (File.Open(stroutputfile,"r")==false){logfile.Write("File.Open(%s) failed.\n",stroutputfile); sleep(60); continue;}    char strBuffer[1001],strURL[501],strFullFileName[301],strFileName[101];  // 得到全部的图片文件名while (true){memset(strBuffer,0,sizeof(strBuffer));memset(strURL,0,sizeof(strURL));memset(strFullFileName,0,sizeof(strFullFileName));memset(strFileName,0,sizeof(strFileName));  if (File.Fgets(strBuffer,1000)==false) break;  if (MatchFileName(strBuffer,"*PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20*.JPG*")==false) continue;  // logfile.Write("%s",strBuffer);        if (GetURL(strBuffer,strURL,strFileName)==false) continue; //解析出url和文件名       snprintf(strFullFileName,300,"%s/%s",argv[3],strFileName); //文件已存在,不采集if (access(strFullFileName,F_OK)==0) continue;  logfile.Write("download %s ",strFileName); //调用wget获取文件memset(strwgetclient,0,sizeof(strwgetclient));snprintf(strwgetclient,500,"wget \"%s\" -o %s/wgetrain24.log -O %s",strURL,argv[2],strFullFileName);system(strwgetclient);  if (access(strFullFileName,F_OK)==0) logfile.WriteEx("ok.\n");else logfile.WriteEx("failed.\n");}  File.CloseAndRemove();sleep(60);}return 0;
}bool GetURL(char *strBuffer,char *strURL,char *strFileName)
{char *start,*end;start=end=0;if ((start=strstr(strBuffer,"http"))==0) return false;if ((end=strstr(start,"\""))==0) return false; //找双引号strncpy(strURL,start,end-start);strcpy(strFileName,strstr(strURL,"PWCP"));return true;
}
void EXIT(int sig)
{if (sig > 0) signal(sig,SIG_IGN);logfile.Write("catching the signal(%d).\n",sig);logfile.Write("wgetclient exit.\n");exit(0);
}

在这里插入图片描述

9.非结构化数据存储:blob,pzhrain24file

在这里插入图片描述

// 本程序演示如何把磁盘文件的文本文件写入Oracle的BLOB字段中。
//filetoblob.cpp,实时生成的不要存oracle的blob字段
#include "_ooci.h"
int main(int argc,char *argv[])
{connection conn;  // 连接数据库,返回值0-成功,其它-失败// 失败代码在conn.m_cda.rc中,失败描述在conn.m_cda.message中。if (conn.connecttodb("scott/tiger@snorcl11g_198","Simplified Chinese_China.ZHS16GBK") != 0){printf("connect database %s failed.\n%s\n","scott/tiger@orcl",conn.m_cda.message); return -1;}    sqlstatement stmt(&conn);  // SQL语言操作类 // 为了方便演示,把goods表中的记录全删掉,再插入一条用于测试的数据。// 不需要判断返回值stmt.prepare("\BEGIN\delete from goods;\insert into goods(id,name,pic) values(1,'商品名称',empty_blob());\END;");  // 执行SQL语句,一定要判断返回值,0-成功,其它-失败。if (stmt.execute() != 0){printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;}// 使用游标从goods表中提取id为1的pic字段// 注意了,同一个sqlstatement可以多次使用// 但是,如果它的sql改变了,就要重新prepare和bindin或bindout变量stmt.prepare("select pic from goods where id=1 for update");stmt.bindblob();// 执行SQL语句,一定要判断返回值,0-成功,其它-失败。if (stmt.execute() != 0){printf("stmt.execute() failed.\n%s\n%s\n",stmt.m_sql,stmt.m_cda.message); return -1;}// 获取一条记录,一定要判断返回值,0-成功,1403-无记录,其它-失败。if (stmt.next() != 0) return 0;  // 把磁盘文件pic_in.jpg的内容写入BLOB字段,一定要判断返回值,0-成功,其它-失败。if (stmt.filetolob((char *)"pic_in.jpg") != 0){printf("stmt.filetolob() failed.\n%s\n",stmt.m_cda.message); return -1;}  conn.commit(); // 提交事务return 0;
}

在这里插入图片描述
如下文件信息放入表中。
在这里插入图片描述

// pzhrain24file.cpp
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile;
CDir Dir;
// 处理数据文件
bool _pzhrain24file(char *strargv2,char *strargv4,char *strargv5);
connection conn;
void EXIT(int sig);int main(int argc,char *argv[])
{if (argc!=7){printf("\n本程序用于处理全国逐小时雨量实况图片文件。\n\n");printf("/htidc/shqx/bin/pzhrain24file logfilename connstr srcpathname dstpathname tname timetvl\n");printf("例如:/htidc/shqx/bin/pzhrain24file /log/shqx/pzhrain24file.log shqx/pwdidc@snorcl11g_198 /data/wfile/zhrain24 /qxfile/zhrain24 T_ZHRAIN24 30\n");printf("logfilename 本程序运行的日志文件名。\n");printf("connstr 数据库的连接参数。\n");printf("srcpathname 原始文件存放的目录,文件命名如PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20191101070000000.JPG。\n");printf("dstpathname 目标文件存放的目录,文件按yyyy/mm/dd组织目录,重命名为zhrain24_yyyymmddhh24miss.jpg。\n");printf("tname 数据存放的表名。\n");printf("timetvl 本程序运行的时间间隔,单位:秒。\n");return -1;}CloseIOAndSignal();signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[1],"a+")==false){printf("打开日志文件失败(%s)。\n",argv[1]); return -1;}logfile.Write("程序启动。\n");while (true){// logfile.Write("开始扫描目录。\n");// 扫描数据文件存放的目录,只匹配"PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20*.JPG"if (Dir.OpenDir(argv[3],"PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20*.JPG",1000,true,true)==false){logfile.Write("Dir.OpenDir(%s) failed.\n",argv[3]); sleep(atoi(argv[6])); continue;}    while (true) // 逐个处理目录中的数据文件{if (Dir.ReadDir()==false) break;if (_pzhrain24file(argv[2],argv[4],argv[5])==false) {logfile.WriteEx("失败。\n"); continue;}}if (conn.m_state==1) conn.disconnect(); sleep(atoi(argv[6]));}return 0;
}
void EXIT(int sig)
{logfile.Write("程序退出,sig=%d\n\n",sig);exit(0);
}//1111111111111111111111111111111111111111111处理数据文件
bool _pzhrain24file(char *strargv2,char *strargv4,char *strargv5)
{char strddatetime[21];   // 文件的数据时间,格式yyyymmddhh24missmemset(strddatetime,0,sizeof(strddatetime));strncpy(strddatetime,strstr(Dir.m_FileName,"20"),14);//搜索文件名PWCP_TWC…中20,后面取14位,重命名为zhrain24_%s.jpgchar strdstfilename[301];  // 目标文件名,不带路径memset(strdstfilename,0,sizeof(strdstfilename));snprintf(strdstfilename,300,"zhrain24_%s.jpg",strddatetime);char strdstfilepath[301];  // 目标文件存放的目录memset(strdstfilepath,0,sizeof(strdstfilepath));snprintf(strdstfilepath,300,"%s/",strargv4);strncat(strdstfilepath,strddatetime,4);     strcat(strdstfilepath,"/");  // 年的子目录strncat(strdstfilepath,strddatetime+4,2);   strcat(strdstfilepath,"/");  // 月的子目录strncat(strdstfilepath,strddatetime+6,2);   strcat(strdstfilepath,"/");  // 日的子目录char strfulldstfilename[301]; // 目标文件名,全路径memset(strfulldstfilename,0,sizeof(strfulldstfilename));snprintf(strfulldstfilename,300,"%s%s",strdstfilepath,strdstfilename);// 如果文件已处理(目标文件已存在),直接返回成功。if (access(strfulldstfilename,F_OK) == 0) return true;if (conn.m_state==0){if (conn.connecttodb(strargv2,"Simplified Chinese_China.ZHS16GBK")!=0){logfile.Write("connect database(%s) failed.\n%s\n",strargv2,conn.m_cda.message); return false;}// logfile.Write("连接数据库成功。\n");}// 把源文件复制到目标文件if (COPY(Dir.m_FullFileName,strfulldstfilename)==false) {logfile.Write("复制文件COPY(%s,%s)...failed.\n",Dir.m_FullFileName,strfulldstfilename); return false;}// 把非结构化数据文件写入oracle数据库的表中if (FileToTable(&conn,&logfile,strargv5,strfulldstfilename,strddatetime)!=0){logfile.Write("把文件%s存入%s...failed.\n",strfulldstfilename,strargv5);  return false;}logfile.Write("把文件%s存入%s...ok.\n",strfulldstfilename,strargv5);  return true;
}

在这里插入图片描述
在这里插入图片描述

10.磁盘/cpu信息收集:内存信息free -m,和top命令查看的内存是一样的,也在系统文件/proc/meminfo

在这里插入图片描述

//diskinfo.cpp,写入xml文件中再入库
#include "_public.h"
void EXIT(int sig);
CLogFile logfile;int main(int argc,char *argv[])
{if (argc != 4){printf("\n");printf("Using:./diskinfo hostname logfilename outputpath\n");printf("Example:/htidc/public/bin/diskinfo 118.89.50.198 /tmp/htidc/log/diskinfo.log /tmp/htidc/monclient\n\n");printf("此程序调用df命名,把本服务器的磁盘使用率信息写入xml文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的xml文件存放的目录。\n");printf("此程序运行在需要监控的服务器上(本程序只适用Linux系统),采集后的xml文件由文件传输程序发送给数据处理服务程序入库。\n\n\n");return -1;}CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+") == false){printf("logfile.Open(%s) failed.\n",argv[2]); return -1;}FILE *fp=0;if ( (fp=popen("df -k --block-size=1M","r")) == NULL ){logfile.Write("popen(df -k --block-size=1M) failed.\n"); return false;}char strXMLFileName[301],strLocalTime[21];memset(strXMLFileName,0,sizeof(strXMLFileName));memset(strLocalTime,0,sizeof(strLocalTime));LocalTime(strLocalTime,"yyyymmddhh24miss");snprintf(strXMLFileName,300,"%s/diskinfo_%s_%s.xml",argv[3],strLocalTime,argv[1]);CFile XMLFile;if (XMLFile.OpenForRename(strXMLFileName,"w+") == false ){logfile.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName); pclose(fp); return -1;}XMLFile.Fprintf("<data>\n");CCmdStr CmdStr;char strBuffer[1024],strLine[500];while (true){memset(strBuffer,0,sizeof(strBuffer));if (FGETS(fp,strBuffer,500) == false) break;// 如果没有找到“%”,就再读取一行,与strBuffer拼起来if (strstr(strBuffer,"%") == 0){memset(strLine,0,sizeof(strLine));if (FGETS(fp,strLine,500) == false) break;strcat(strBuffer," "); strcat(strBuffer,strLine);}// 删除字符串前后的空格和换行符DeleteLRChar(strBuffer,' '); DeleteLRChar(strBuffer,'\n');// 把字符串中间的多个空格全部转换为一个空格UpdateStr(strBuffer,"  "," ");// 把全内容全部转换为小写ToLower(strBuffer);// 除了磁盘信息,还有可能是内存,SMB等其它文件,都丢弃掉if (strncmp(strBuffer,"/dev",4) != 0) continue;CmdStr.SplitToCmd(strBuffer," ");if (CmdStr.CmdCount() != 6) continue;char strusep[21];memset(strusep,0,sizeof(strusep));strcpy(strusep,CmdStr.m_vCmdStr[4].c_str());UpdateStr(strusep,"%","");char strLocalTime[21];memset(strLocalTime,0,sizeof(strLocalTime));LocalTime(strLocalTime,"yyyymmddhh24miss");XMLFile.Fprintf(\"<nodip>%s</nodip>"\"<crttime>%s</crttime>"\"<filesystem>%s</filesystem>"\"<total>%0.02f</total>"\"<used>%0.02f</used>"\"<available>%0.02f</available>"\"<usep>%0.02f</usep>"\"<mount>%s</mount><endl/>\n",argv[1],strLocalTime,CmdStr.m_vCmdStr[0].c_str(),atof(CmdStr.m_vCmdStr[1].c_str())/1024.0,atof(CmdStr.m_vCmdStr[2].c_str())/1024.0,atof(CmdStr.m_vCmdStr[3].c_str())/1024.0,(atof(CmdStr.m_vCmdStr[2].c_str())/atof(CmdStr.m_vCmdStr[1].c_str()))*100.0,CmdStr.m_vCmdStr[5].c_str());}XMLFile.Fprintf("</data>\n");pclose(fp);XMLFile.CloseAndRename();logfile.Write("create %s ok.\n",strXMLFileName);exit(0);
}void EXIT(int sig)
{if (sig > 0) signal(sig,SIG_IGN);logfile.Write("catching the signal(%d).\n",sig);logfile.Write("diskinfo exit.\n");exit(0);
}

cpuinfo.cpp思路是定义三个结构体变量,加载cpu信息到结构体里,睡60s,再继续加载cpu信息到结构体里,再将两结构体成员相减,就可以知道一分钟内cpu情况,采用的是一分钟信息。vi /proc/stat如下。
在这里插入图片描述

//cpuinfo.cpp
#include "_public.h"
void EXIT(int sig);
CLogFile logfile;
struct st_cpuinfo
{double user;double sys;double wait;double nice;double idle;double irq;double softirq;double total;
};
struct st_cpuinfo stcpuinfo1,stcpuinfo2,stcpuinfo3;
bool LoadCPUInfo(struct st_cpuinfo &stcpuinfo);int main(int argc,char *argv[])
{if (argc != 4){printf("\n");printf("Using:./cpuinfo hostname logfilename outputpath\n");printf("Example:/htidc/public/bin/cpuinfo 118.89.50.198 /tmp/htidc/log/cpuinfo.log /tmp/htidc/monclient\n\n");printf("此程序读取/proc/stat文件,把本服务器的CPU使用率信息写入xml文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的xml文件存放的目录。\n");printf("此程序运行在需要监控的服务器上(本程序只适用Linux系统),采集后的xml文件由文件传输程序发送给数据处理服务程序入库。\n\n\n");return -1;}//memset(strHostName,0,sizeof(strHostName));//strncpy(strHostName,argv[2],20);CloseIOAndSignal(); signal(SIGINT,EXIT); signal(SIGTERM,EXIT);if (logfile.Open(argv[2],"a+") == false){printf("logfile.Open(%s) failed.\n",argv[2]); return -1;}memset(&stcpuinfo1,0,sizeof(struct st_cpuinfo));memset(&stcpuinfo2,0,sizeof(struct st_cpuinfo));memset(&stcpuinfo3,0,sizeof(struct st_cpuinfo));if (LoadCPUInfo(stcpuinfo1) ==false) return -1;  sleep(60);if (LoadCPUInfo(stcpuinfo2) ==false) return -1;stcpuinfo3.user=stcpuinfo2.user-stcpuinfo1.user;stcpuinfo3.sys=stcpuinfo2.sys-stcpuinfo1.sys;stcpuinfo3.wait=stcpuinfo2.wait-stcpuinfo1.wait;stcpuinfo3.nice=stcpuinfo2.nice-stcpuinfo1.nice;stcpuinfo3.idle=stcpuinfo2.idle-stcpuinfo1.idle;stcpuinfo3.irq=stcpuinfo2.irq-stcpuinfo1.irq;stcpuinfo3.softirq=stcpuinfo2.softirq-stcpuinfo1.softirq;stcpuinfo3.total=stcpuinfo3.user+stcpuinfo3.sys+stcpuinfo3.wait+stcpuinfo3.nice+stcpuinfo3.idle+stcpuinfo3.irq+stcpuinfo3.softirq;char strLocalTime[21];memset(strLocalTime,0,sizeof(strLocalTime));LocalTime(strLocalTime,"yyyymmddhh24miss");char strXMLFileName[301];memset(strXMLFileName,0,sizeof(strXMLFileName));snprintf(strXMLFileName,300,"%s/cpuinfo_%s_%s.xml",argv[3],strLocalTime,argv[1]);CFile XMLFile;if (XMLFile.OpenForRename(strXMLFileName,"w+") == false ){logfile.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName); return -1;}XMLFile.Fprintf("<data>\n");XMLFile.Fprintf("<nodip>%s</nodip><crttime>%s</crttime><user>%0.02f</user><sys>%0.02f</sys><wait>%0.02f</wait><nice>%0.02f</nice><idle>%0.02f</idle><usep>%0.02f</usep><endl/>\n",argv[1],strLocalTime,stcpuinfo3.user/stcpuinfo3.total*100.0,stcpuinfo3.sys/stcpuinfo3.total*100.0,stcpuinfo3.wait/stcpuinfo3.total*100.0,stcpuinfo3.nice/stcpuinfo3.total*100.0,stcpuinfo3.idle/stcpuinfo3.total*100.0,100.0-stcpuinfo3.nice/stcpuinfo3.total*100.0);XMLFile.Fprintf("</data>\n");XMLFile.CloseAndRename();logfile.Write("create %s ok.\n",strXMLFileName);exit(0);
}
void EXIT(int sig)
{if (sig > 0) signal(sig,SIG_IGN);logfile.Write("catching the signal(%d).\n",sig);logfile.Write("cpuinfo exit.\n");exit(0);
}bool LoadCPUInfo(struct st_cpuinfo &stcpuinfo)
{CFile CPUFile;if (CPUFile.Open("/proc/stat","r") == false ){logfile.Write("CPUFile.OpenForRead(/proc/stat) failed.\n"); return false;}CCmdStr CmdStr;char strBuffer[1024];while (true){memset(strBuffer,0,sizeof(strBuffer));if (CPUFile.FFGETS(strBuffer,500) == false) break;// 删除字符串前后的空格DeleteLRChar(strBuffer,' ');// 把字符串中间的多个空格全部转换为一个空格UpdateStr(strBuffer,"  "," ");ToLower(strBuffer);CmdStr.SplitToCmd(strBuffer," ");if (strcmp(CmdStr.m_vCmdStr[0].c_str(),"cpu")==0) {stcpuinfo.user=atof(CmdStr.m_vCmdStr[1].c_str());stcpuinfo.sys=atof(CmdStr.m_vCmdStr[2].c_str());stcpuinfo.wait=atof(CmdStr.m_vCmdStr[3].c_str());stcpuinfo.nice=atof(CmdStr.m_vCmdStr[4].c_str());stcpuinfo.idle=atof(CmdStr.m_vCmdStr[5].c_str());stcpuinfo.irq=atof(CmdStr.m_vCmdStr[6].c_str());stcpuinfo.softirq=atof(CmdStr.m_vCmdStr[7].c_str());return true;}}logfile.Write("Read /proc/stat failed.\n"); return false;
}

在这里插入图片描述
vi /tmp/htdic/monclient/cpu*,如下是收集到的信息。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/858248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RepVGG论文阅读笔记

目录 RepVGG: Making VGG-style ConvNets Great Again摘要INTRODUCTION—简介RepVGG BlockModel Re-parameterization -- 模型重参数化融合Conv2d和BN&#xff0c;将三个分支上的卷积算子和BN算子都转化为卷积算子&#xff08;包括卷积核和偏置&#xff09;多分支融合&#xff…

Vue elementui表格

去除表头 <el-table:data"tableData"stripestyle"width: 100%":cell-style"{ text-align: justify-all }":show-header"false"></el-table>合并 <template><div class"elife-container"><el-ro…

蓝桥杯 经典算法题 实现归并排序

题目&#xff1a; 题解&#xff1a; 不断地将数组不断向下平均分为两部分&#xff0c;直到每个子数组中元素数量为1&#xff0c;这样就可以将相邻两个数组长度为1的数组看作是单调数组合并为一个大的单调数组&#xff0c;如此不断向上合并出最终的单调数组。 #include <bi…

BC64 牛牛的快递(c++)

牛牛的快递 题目描述输入描述输出描述示例代码 解题思路例如 题目描述 牛牛正在寄快递&#xff0c;他了解到快递在 1kg 以内的按起步价 20 元计算&#xff0c;超出部分按每 kg 1元计算&#xff0c;不足 1kg 部分按 1kg计算。如果加急的话要额外付五元&#xff0c;请问牛牛总共要…

【计算机网络篇】数据链路层(12)交换机式以太网___以太网交换机

文章目录 &#x1f354;交换式以太网&#x1f6f8;以太网交换机 &#x1f354;交换式以太网 仅使用交换机&#xff08;不使用集线器&#xff09;的以太网就是交换式以太网 &#x1f6f8;以太网交换机 以太网交换机本质上就是一个多接口的网桥&#xff1a; 交换机的每个接口…

国产大模型技术创新分析

国产模型百舸争流&#xff0c;技术创新百花齐放 2023年下半年起&#xff0c;国内大模型领域迎来“百模大战”&#xff0c;各大厂商纷纷加速生成式AI的研发与突破&#xff0c;模型持续迭代升级&#xff0c;展现了人工智能技术的蓬勃发展与无限潜力。 中国大模型市场迅猛发展&am…

【Linux详解】冯诺依曼架构 | 操作系统设计 | 斯坦福经典项目Pintos

目录 一. 冯诺依曼体系结构 (Von Neumann Architecture) 注意事项 存储器的意义&#xff1a;缓冲 数据流动示例 二. 操作系统 (Operating System) 操作系统的概念 操作系统的定位与目的 操作系统的管理 系统调用和库函数 操作系统的管理&#xff1a; sum 三. 系统调…

Structured Steaming结构化流详解:大案例解析(第12天)

系列文章目录 一、结构化流介绍&#xff08;了解&#xff09; 二、结构化流的编程模型&#xff08;掌握&#xff09; 三、Spark 和 Kafka 整合&#xff0c;流处理&#xff0c;批处理演示&#xff08;掌握&#xff09; 四、物联网数据分析案例&#xff08;熟悉&#xff09; 文章…

华硕笔记本重装系统详细操作,图文教程体验Win11如何重装系统

随着科技的不断发展&#xff0c;电脑操作系统的步骤也在不断更新迭代。对于华硕笔记本用户来说&#xff0c;升级到Windows 11操作系统可以带来更好的使用体验。本文将通过图文教程的形式&#xff0c;详细介绍华硕笔记本重装Windows 11系统的操作步骤&#xff0c;帮助用户顺利完…

LeetCode | 344.反转字符串

设置头尾两个指针&#xff0c;依靠中间变量temp交换头尾指针所指元素&#xff0c;头指针后移&#xff0c;尾指针前移&#xff0c;直到头尾指针重合或者头指针在尾指针后面一个元素 class Solution(object):def reverseString(self, s):""":type s: List[str]:r…

如和完全免费快速访问外网?有亿点点不便利罢了

很鸡肋&#xff0c;但是可以试试 这个手机是真的可以使用谷歌的 不得不说有点意思&#xff0c;但肯定没啥用 地址跳转

怎么用Excel生成标签打印模板,自动生成二维码

环境&#xff1a; EXCEL2021 16.0 问题描述&#xff1a; 怎么用excel生成标签打印模板自动生成二维码 解决方案&#xff1a; 在Excel中生成标签打印模板并自动生成二维码&#xff0c;可以通过以下几个步骤完成&#xff1a; 1. 准备数据 首先&#xff0c;确保你的Excel表…

SyntaxWarning警告

为什么conda环境运行hipcc vector_add.cpp -o vector_add -v会出现&#xff1a; SyntaxWarning: invalid escape sequence \w staticVars(search_namere.compile("gfx[0-9a-fA-F](:[-:\w])?")) SyntaxWarning: invalid escape sequence \A line_search_term re…

Vue3 【仿 react 的 hook】封装 useTitle

效果预览 页码加载时&#xff0c;自动获取网页标题通过input输入框&#xff0c;可以实时改变网页标题 代码实现 index.vue <template><h1>网页的标题为&#xff1a; {{ titleRef }}</h1><p>通过input输入框实时改变网页的标题 <input v-model"…

【Vision AI v2开箱之SenseCraft AI猫狗识别Arduino教程】

【Vision AI v2开箱之SenseCraft AI猫狗识别Arduino教程】 1. 前言2. 实验材料2.1 Grove Vision AI Module V22.1.1 特征2.1.2 硬件概述2.1.3 启动/重置/程序2.1.4 驱动 2.2 ESP32C32.2.1 引脚图2.2.2 组件概述2.2.3 电源引脚 2.3 SenseCraft AI Model Assistant2.3.1 部署的模…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【13】压力压测JMeter-性能监控jvisualvm 压力测试概述性能指标 JMeter基本使用添加线程组添加 HTTP 请求添加监听器启动压测&查看分析结果JMeter Address Already in use 错误解决 性…

Hive数据锁问题处理

在测试环境有定时任务会定期将flume采集的数据load到hive表中&#xff0c;在查看yarn application过程中发现load操作没有执行&#xff0c;且后续的任务在上一个任务执行结束后很久才开始。感觉像是阻塞一样&#xff0c;于是手动执行相关脚本&#xff0c;发现也是会卡住&#x…

【Linux】进程间通信上 (1.5万字详解)

目录 一.进程间通信介绍 1.1进程间通信的目的 1.2初步认识进程间通信 1.3进程间通信的种类 二.匿名管道 2.1何为管道 2.1实现原理 2.3进一步探寻匿名管道 2.4编码实现匿名管道通信 2.5管道读写特点 2.6基于管道的进程池设计 三.命名管道 3.1实现原理 3.2代码实现 四.…

视觉理解与图片问答,学习如何使用 GPT-4o (GPT-4 Omni) 来理解图像

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、引言 OpenAI 最新发布的 GPT-4 Omni 模型&#xff0c;也被称为 GPT-4o&#xff0c;是一个多模态 AI 模型&#xff0c;旨在提供更加自然和全面的人机交互体验。 GPT-4o 与 GPT-4 Turbo 都具备视觉功…

SuiNS发布子名及新命名标准,推动Web3身份结构的进步

SuiNS子名是Sui Name Service的强大扩展&#xff0c;最近与新命名标准一起发布。子名允许用户在一个主要的SuiNS名下创建额外的自定义身份&#xff0c;而无需额外费用。用户 gia 可以创建如 gaminggia 或 lendinggia 这样的子名&#xff0c;从而增强个人组织和支持群组与组织的…