关于数据库触发器的个人理解/注解

在做智能农场项目过程中,有一个问题:这个项目是基于c/s架构,但是有两个服务器,分别是与感知层交互的服务器、与QT客户端交互的服务器,如何做到QT服务器发出反控命令到数据库后能够使底层服务器实时读取命令并执行,想到几个方法:1、QT服务器与硬件服务器进程间通信,但考虑到以后QT服务器可能改为WEB服务器,这时候进程间通信不适用;2、如果采用服务器定时轮询查看,可能会因不及时造成业务上的不便。 不提闲话了,以下为个人利用mysql触发器在C项目中的用法:

create  function  sock_mysql  RETURNS INTEGER SONAME 'libmysqludf2.so'  //创建sock_mysql()函数链接libmysqludf2.so 库
delimiter |     //修改mysql语句以“|”结尾,触发器使用完后记得改回来,避免影响以后mysql语句的正常使用
create trigger Contrl_Qt  after update on  control  for each row    //在每次更新“control”表(每行都适用)之后创建名为Contrl_Qt的触发器
        //也可以将“after”改为“before”,意为“之前”
        //也可以将“update”改为“insert”等
begin       //以下为触发器函数实现代码
    declare ab varchar(20);    //使用关键字定义ab变量
    set ab=sock_mysql(new.Q_value);  //set关键字给ab赋值
end|        //以“|”结尾,结束mysql语句

这里涉及到mysql的UDF(User defined function):sock_mysql()函数(名字随意)、初始化函数sock_mysql_init()、释放函数sock_mysql_deinit()
以下为供学习代码,作用为:在sock_mysql()函数内建立TCP客户端,连接服务器向服务器发送从数据库读到的数据。
————附上大神“印风”关于UDF讲解的链接:(http://blog.csdn.net/zhaiwx1987/article/details/6902623)

#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP
#endif
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<unistd.h>
#include <my_global.h>
#include <my_sys.h>
#include<mysql.h>
#include<sys/socket.h>
#include<errno.h>
#include<arpa/inet.h>
#define ERR(msg) do{\
                fprintf(stderr,"[%s:%d]%s:%s",__FILE__,__LINE__,msg,strerror(errno));\
                exit(-1);\
}while(0)
#if 1
/* These must be right or mysqld will not find the symbol! */
DLLEXP
my_bool sock_mysql(UDF_INIT *initid,UDF_ARGS *args,char *is_null,char *error);
DLLEXP
my_bool sock_mysql_init(UDF_INIT *initid,UDF_ARGS *args,char *message);

DLLEXP
void sock_mysql_deinit(UDF_INIT *initid);
#endif
my_bool sock_mysql_init(UDF_INIT *initid,UDF_ARGS *args,char *message)
{

                if(args->arg_count!=1)
                {
                                strcpy(message,"Expected exactly 2 arguments");     
                                return 1;
                }
                if(args->arg_type[0]!=STRING_RESULT)
                                //      if(args->arg_type[0]!=INT_RESULT)
                {
                                strcpy(message,"Expected string type for name parameter");      
                                return 1;
                }
                //  args->arg_type[1]=INT_RESULT;
                if((initid->ptr=malloc( args->lengths[0] +1))==NULL)
                {
                                strcpy(message,"Could not allocate memory");        
                                return 1;
                }   
                return 0;
}


void sock_mysql_deinit(UDF_INIT *initid)
{
                if (initid->ptr!=NULL)
                {   free(initid->ptr);}
}


my_bool sock_mysql(UDF_INIT *initid,UDF_ARGS *args,char *is_null,char *error)
{
                struct sockaddr_in myaddr;
                char sndbuf[20];
                char buff[20];
                                memcpy(sndbuf,args->args[0],args->lengths[0]);
                *(sndbuf+args->lengths[0])='\0';
                //  float s=args->args[1];
                int sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                if(sockfd == -1)
                                ERR("socket");
                memset(&myaddr,0,sizeof(myaddr));
                myaddr.sin_family = AF_INET;
                myaddr.sin_port = htons(8083);
                myaddr.sin_addr.s_addr = inet_addr("192.168.197.128");
                if(connect(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) == -1)
                {
                                ERR("connect");
                }
                //  sprintf(sndbuf,"%s#%.2f",buff,s);
                //  printf("%s",sndbuf);
                //  strcpy(sndbuf,"hello");
                send(sockfd,sndbuf,1024,0);
                close(sockfd);
                return 0;

}

UDF需要生成库并存放于mysql路径下,库名应与触发器中提到的库名一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值