<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      左眼水星

      導航

      MySQL自定義函數(User Define Function)開發實例——發送TCP/UDP消息

      開發背景

      監控數據庫中某個字段的值,當它改為特定值時向通知其它系統以執行業務邏輯。

      實現思路

      監控數據庫中特定字段值的變化可以用數據庫觸發器實現,在觸發器中發送udp消息通知其它系統。

      難點在于觸發器中能執行的都是數據庫定義好的方法,它們都無法實現這個需求。自定義函數(User Define Function)允許我們創建自己的函數,實現自己的邏輯,就像MySQL本來就有這個函數一樣。

      我們實現這樣一個自定義的函數,接收一個字符串參數,然后將這個字符傳通過udp發送到指定端口。

      開發前準備

      MySQL自定義函數僅支持C/C++開發,所以需要一些C/C++的基礎。

      這里以在Windows中使用Visual Studio2022開發進行介紹。

      創建一個C++庫項目,添加依賴項libmysql.lib、ws2_32.lib,引入頭文件"mysql.h"  <ws2tcpip.h>

      自定義函數我這里取名為SendG,使用方式為SendG(string)

      MySQL自定義函數設計說明

      提前說明:本文只介紹滿足前面需求下的自定義函數設計方法。

      這里要涉及兩個函數

      bool SendG_init(UDF_INIT* init, UDF_ARGS* args, char* message)   這個后綴_init方法顧名思義是一個初始化函數

      void SendG(UDF_INIT* init, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error) 是主體函數

      當我們每次調用SendG(string) 時會先調用 _init后綴的函數,然后才會調用主體函數中的業務邏輯。因此我們可以在SendG_init函數中檢查參數是否正確,在SendG函數中執行具體的業務邏輯。

      函數的命名是固定的必須取名為 xxxx_init和xxxx

      至于UDF_INIT   UDF_ARGS等結構的使用方法則不用擔心,MySQL的頭文件中有詳細介紹,基本一看就大概知道怎么用,例如以下是UDF_ARGS的定義:

      本文會用到arg_count、arg_type、lengths這幾個字段,通過他們的命名結合注釋就可以知道具體含義,這里不在啰嗦。

      具體實現代碼

      #include "pch.h"
      #include "mysql.h"
      #include <ws2tcpip.h>
      extern "C" {
          __declspec(dllexport)
              bool SendG_init(UDF_INIT* tinit, UDF_ARGS* args, char* message) {
              if (args->arg_count != 1) {
                  char ms[]{ "Only one parameter is accepted in the call to udf 'SendG'" };
                  memcpy_s(message, sizeof(ms), ms, sizeof(ms));
                  return true;
              }
              else if (args->arg_type[0] != STRING_RESULT) {
                  char ms[]{ "Only string parameters are accepted in the call to udf 'SendG'" };
                  memcpy_s(message, sizeof(ms), ms, sizeof(ms));
                  return true;
              }
              return false;
          }
          __declspec(dllexport)
              void SendG(UDF_INIT* tinit, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error) {
              SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
              sockaddr_in RecvAddr{};
              RecvAddr.sin_family = AF_INET;
              RecvAddr.sin_port = htons(54321);
              inet_pton(AF_INET, "127.0.0.1", &RecvAddr.sin_addr);
              *is_null = 1;
              sendto(sock, args->args[0], args->lengths[0], 0, (SOCKADDR*)&RecvAddr, sizeof(RecvAddr));
              closesocket(sock);
          }
      }

      我們在SendG_init中檢查參數的數量和類型是否正確,SendG_init的返回true代表有錯誤,返回false才表示沒問題(這里和WinAPI比較像,返回的HRESULT是0表示正常執行 )。參數錯誤時向message寫入具體的錯誤提示,幫助調用者正確使用我們的函數。

      然后會執行SendG主體函數,這里創建一個SOCKET使用UDP協議將傳入的字符串發送給本機的54321端口,最后關閉SOCKET。

      這里需要注意兩點:

      1、函數必須使用extern "C"導出C語言標準的函數

      2、在這個例子中SendG方法是不需要有執行結果的,所以它的返回值類型是void,其次因為沒有返回值所以這里必須使用*is_null=1允許方法返回NULL。如果有返回值則正常返回具體的類型,可選的返回值類型在Item_result中定義(init中檢查參數類型時就用到了)它與UDF_ARGS在同一個頭文件中,這里就不具體展開了。

      自定義函數的注冊與卸載

      在使用前需要先部署注冊我們的自定義方法,相當于告訴數據庫有這個方法。

      首先將生成的dll放在MySQL的plugin目錄中,可使用select @@plugin_dir查詢。然后使用CREATE FUNCTION SendG RETURNS string SONAME 'SUDP.dll'  向數據庫注冊函數SendG

      現在執行select SendG('abcde')就會向54321端口發送abcde了(可以改寫 SendG讓它接受兩個參數,把端口號作為第二個參數,這樣SendG方法就更加靈活了)

      卸載SendG使用DROP FUNCTION SendG;

      注冊和卸載都不需要重啟MySQL服務。

      總結

      MySQL的UDF提供了開發自定義函數的功能,實際在這里可以執行我們自己寫的任意代碼(別說發UDP/TCP消息了就是發郵件都行)。

      業務系統可以通過SQL給數據庫系統傳遞信息,UDF技術則幫助我們實現了數據庫系統向業務系統傳遞消息。

      posted on 2024-06-25 23:36  左眼水星  閱讀(308)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 波多野结衣久久一区二区| 亚洲国产区男人本色vr| 国产午夜福利精品视频| 亚洲 欧美 清纯 校园 另类| 综合成人亚洲网友偷自拍| 丰满少妇呻吟高潮经历| 亚洲中文字幕在线无码一区二区| 亚洲av乱码一区二区| 2021国产精品一卡2卡三卡4卡| 久久亚洲国产五月综合网| 一本久道久久综合狠狠躁av| 亚洲国产成人无码电影| 亚洲中文字幕国产综合| 免费拍拍拍网站| 亚洲国产精品毛片在线看| 亚洲人成电影网站 久久影视| 无码免费中文字幕视频| 国产精品www夜色视频| 色偷偷www.8888在线观看| 日韩一区精品视频一区二区| 亚洲人午夜精品射精日韩| 亚洲乱熟女一区二区三区| 九九热在线免费视频观看| 亚洲最大成人av在线天堂网| 中年国产丰满熟女乱子正在播放| 香蕉EEWW99国产精选免费| 亚洲精品中文字幕尤物综合 | 久久精品蜜芽亚洲国产av| 开心五月激情综合久久爱| 国产一区二区波多野结衣| av激情亚洲男人的天堂| 国产WW久久久久久久久久| 波多野结衣久久一区二区| 国产 另类 在线 欧美日韩| 国产高清乱码又大又圆| 精品亚洲成A人在线观看青青| 国产精品日韩中文字幕| 国产手机在线αⅴ片无码观看| 亚洲av色在线观看国产| 国产99视频精品免费视频36| bt天堂新版中文在线|