dm达梦数据库 创建 YEARWEEK 外部函数

news2024/11/24 1:01:11

这里写目录标题

  • 数据库环境
  • 创建方式
    • 一、C 外部函数
    • 二、JAVA 外部函数

数据库环境

类型版本官网下载地址
基础环境Windows 11
Dm8dm8_20230418_x86_win_64.zip链接: 官网

创建方式

一、C 外部函数

(1)C 外部函数是使用 C、C++ 语言编写,在数据库外编译并保存在.dll、.so 共享库文件中,被用户通过 DMSQL 程序调用的函数。
(2)C 外部函数的执行一般通过代理 dmap 工具进行,此时为了执行 C 外部函数,需要先启动 dmap 服务。dmap 执行程序在 DM8
(3) 安装目录的 bin 子目录下,直接执行即可启动 dmap 服务。 同时,结构化的 C 外部函数支持结合 INI 参数 EFC_USE_AP 进行性能优化,当指定参数值为 0 时,结构化的 C 外部函数会在 dmserver 内部调用,不再和 dmap 进行通信,可以提高函数的执行效率。
(4)当用户调用 C 外部函数时,服务器操作步骤如下:首先,确定调用的(外部函数使用的)共享库及函数;然后,通知代理进程工作。代理进程装载指定的共享库,并在函数执行后将结果返回给服务器。

DM8 C 外部函数 提供以下两种方案编写:
  1. 方式一:DM 结构化参数

       de_data 函数名(de_args *args)
       {
       	C语言函数实现体;
       }
    

    (1) <de_data> 返回值类型。de_data 结构体类型如下:

    struct de_data{
    	int  null_flag;   //参数是否为空,1表示非空,0表示空
    	union	//只支持int、double(或精度大于24的float)、char类型。其中float类型在系统内部被转化为double类型执行,相关接口请使用double类型的接口
        {
    		int    v_int;
    		double  v_double;
    		char   v_str[];
    	}data;
    };
    

    (2) <de_args> 参数信类型。de_args 结构体类型如下:

    struct de_args
    {
    	int        n_args;      //参数个数
        de_data*      args;        //参数列表
    };
    

    (3) < C 语言函数实现体 > C 语言函数对应的函数实现体。

  2. 方式二:标量类型参数
    (1) 该方案中,用户不必引用 DM 提供的外部函数接口,可以按照标准的 C 风格编码,使用 C 标量类型作为参数类型。使用该方案编写的 C 函数,只能在使用 X86 CPU 的 64 位非 Windows 系统中,被数据库引用作为外部函数。
    (2) 结构体

      返回类型函数名(参数列表)
      {
      	C语言函数实现体;
      }
    

    (3) 参数说明
    · 返回类型及参数列表中参数的数据类型只支持 int、double(或精度大于 24 的 float)以及 char类型。其中 float 的用法和 double 完全一样;
    参数列表中不支持 out 型参数;
    · 如果参数列表中有 char* 的参数,不必在函数中对其进行释放;为了安全考虑,最好只对其进行只读操作;
    · 如果返回 char类型,返回值必须使用 malloc 申请空间,且必须有结尾 0,不允许直接返回常量或返回参数列表中传入的字符类型参数

  3. 举例创建 YEARWEEK 函数

    3.1 语法格式

    CREATE [OR REPLACE] FUNCTION [IF NOT EXISTS] [<模式名>.]<函数名>[(<参数列表>)] 
    RETURN <返回值类型>
    EXTERNAL '<动态库路径>' [<引用的函数名>] USING < C | CS >;
    

    3.2 新建项目
    使用 Microsoft Visual Studio 2010 新建空项目 dm_udr,新建完毕后,若本机操作系统为 x64,因为 VS 默认的解决方案平台不是 x64,需要在解决方案平台下拉框选择“配置管理器-活动方案解决平台-新建-键入或选择新平台-x64”。在 d:\xx\dm_udr\newp 文件夹中,直接拷入 dmde.lib 动态库和 de_pub.h 头文件。dmde.lib 和 de_pub.h 位于dm安装目录 x:…\dmdbms\include 中。

    3.3 创建函数文件
    在源文件创建 dm_main.c 文件,写入以下代码(C 水平有限,大家可自行优化,嘿):

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    #define  _CRT_SECURE_NO_WARNINGS
    #include "newp/de_pub.h"
    
    /*!
    @brief 计算今天是今年的第几周
    @param [in] nYear  年
    @return uint16_t
    */
    de_data C_YEARWEEK(de_args* args) {
       de_data de_ret;
       char* strDate;
       strDate = de_get_str(args, 0);
       
       //提取年月日
       /*struct tm stm;
       strptime(strDate, "%Y-%m-%d %H:%M:%S", &stm);*/
       //由于windows下没有strptime函数,可以使用scanf来格式化时间,但是报错
       int nYear, nMonth, nday, hour, minute, second;
       //sscanf(strDate, "%d-%d-%d %d:%d:%d", &nYear, &nMonth, &nday, &hour, &minute, &second);
       //使用间隔符提取
       char blank[2] = " ",yi[2] = "-";
       char strDateNew[20];
       strcpy(strDateNew, strDate);
       char* str1 = strtok(strDateNew, blank);
       char* str2 = strtok(str1, yi);
       char* str3 = strtok(NULL, yi);
       char* str4 = strtok(NULL, yi);
       nYear = atoi(str2);
       nMonth = atoi(str3);
       nday = atoi(str4);
       //free(str1); free(str2); free(str3); free(str4);
    
       //计算
       int nWeekCnt = 0, nWeekRemain = 0, nCount = 0;
       switch (nMonth - 1) {
           case 11: nCount += 30;
           case 10: nCount += 31;
           case 9:  nCount += 30;
           case 8:  nCount += 31;
           case 7:  nCount += 31;
           case 6:  nCount += 30;
           case 5:  nCount += 31;
           case 4:  nCount += 30;
           case 3:  nCount += 31;
           case 2:
               if ((nYear % 4 == 0 && nYear % 100 != 0) || nYear % 400 == 0){
                   nCount += 29;
               }
               else{
                   nCount += 28;
               }
           case 1:  nCount += 31;
           default: break;
       }
    
       //蔡勒公式,周几
       int c, y, nWeek;
       if (nYear == 1 || nMonth == 2){
           nYear--;
           nMonth += 12;
       }
       c = nYear / 100;
       y = nYear - c * 100;
       nWeek = (c / 4) - 2 * c + (y + y / 4) + (13 * (nMonth + 1) / 5) + nday - 1;
       while (nWeek < 0) {
           nWeek += 7;
       }
       nWeek %= 7;
    
       // 根据当前天数计算属于一年的第几周
       nCount += nday;
       nWeekCnt = (nCount + (7 - nWeek)) / 7;
       //nWeekRemain = (nCount + (7 - nWeek))%7;
       //uYearWeek = nWeekCnt + ((nWeekRemain == 0) ? 0 : 1);
       //uYearWeek = nWeekCnt ;
       int uYearWeek = nYear * 100 + nWeekCnt;
    
       de_ret = de_return_int(uYearWeek);
       de_str_free(strDate);
       return de_ret;
    }
    

    创建 tt.def 文件,写入以下代码(C_YEARWEEK 为函数名):

    LIBRARY	"tt.dll"
    EXPORTS
    	C_YEARWEEK
    

    3.4 配置项目属性
    右击 dm_udr 项目-属性,点击打开。
    在 配置属性—链接器—输入,添加附加依赖项-编辑增加:newp\dmde.lib
    在 配置属性—链接器—输入,模块定义文件-编辑增加:tt.def
    在 配置属性—高级—字符集:选择使用多字节字符集。
    在 配置属性—常规—输出目录:设为 D:\xx\dm_udr
    在 配置属性—常规—配置类型:选择动态库(.dll)

    3.5 生成 dm_udr 项目
    右击 dm_udr 项目-生成。得到 D:\xx\dm_udr \dm_udr .dll 文件。
    至此,外部函数的使用环境准备完毕。

    3.6 在达梦创建并使用外部函数
    第一步,启动数据库服务器 dmserver、启动 DMAP、启动 DIsql 等服务。
    需要先开启系统允许创建外部函数的开关。通过设置 DM.INI 参数 ENABLE_EXTERNAL_CALL=1 开启。打开DM管理工具执行语句如下:

    SF_SET_SYSTEM_PARA_VALUE('ENABLE_EXTERNAL_CALL',1,0,2);
    //设置完毕后需重启数据库服务器,参数才能生效
    

    第二步,创建外部函数 YEARWEEK

    // 先删除存在的 YEARWEEK 函数
    drop function YEARWEEK;
    // 创建
    CREATE OR REPLACE FUNCTION YEARWEEK(A VARCHAR) 
    RETURN int
    EXTERNAL 'D:\xx\dm_udr\dm_udr.dll' C_YEARWEEK USING C;
    

    第三步,调用 C YEARWEEK 外部函数。语句如下:

    select YEARWEEK('2023-08-18 10:03:50');
    select YEARWEEK(now());
    

    第四步,查看结果,至此 YEARWEEK 实现完毕,等同于 MySQL 的YEARWEEK 函数
    在这里插入图片描述

二、JAVA 外部函数

(1)JAVA 外部函数是使用 JAVA 语言编写,在数据库外编译生成的 jar 包,被用户通过 DMSQL 程序调用的函数。
(2)JAVA 外部函数的执行都通过代理 dmagent 工具进行,为了执行 JAVA 外部函数,需要先启动 dmagent 服务。dmagent 执行程序在 DM8 安装目录的 tool/dmagent 子目录下,其使用说明文档可参看该目录下的《readme》文档。
(3)当用户调用 JAVA 外部函数时,服务器操作步骤如下:首先,确定调用(外部函数使用的)jar 包及函数;然后,通知代理进程工作。代理进程装载指定的 jar 包,并在函数执行后将结果返回给服务器。
(4)需要注意的是,进行 JAVA 外部函数调用应 保证当前用户可以运行 JAVA 命令,否则会导致调用失败。

  1. JAVA 外部函数创建
    1.1 语法格式

    CREATE [OR REPLACE] FUNCTION [IF NOT EXISTS] [<模式名>.]<函数名>[(<参数列表>)] 
    RETURN <返回值类型>
    EXTERNAL '<jar包路径>' <引用函数名> USING JAVA;
    
  2. 举例说明
    例如,写(JAVA 语言)外部函数:testAdd 用于求两个数之和,testStr 用于在一个字符串后面加上 hello。
    首先,生成 jar 包。

    2.1 第一步,使用 eclipse 创建新项目 newp,位于 F:\workspace 文件夹中。

    2.2 第二步,在 newp 项目中,添加包。右击 newp,新建(new)一个 package,命名(name)为 com.test.package1。

    2.3 第三步,在 package1 包中,添加类文件。右击 src,新建(new)一个 class,命名(name)为 test。Modifiers 选择 public。class 文件内容如下:

    package com.test.package1;  
    public class test {
      public static int testAdd(int a, int b) {
      	return a + b;
      }
      public static String testStr(String str) {
      	return str + " hello";
      }
    }
    

    2.4 第四步,生成 jar 包。在 newp 项目中,右击,选中 EXPORT,选择 Java\JAR file,取消.classpath 和.project 的勾选。目标路径 JAR file 设置为:E:\test.jar,然后 finish

    2.5 第五步,查看 E 盘中 test.jar。已经存在。

    2.6 第六步,在安装目录的…\dmdbms\bin 中创建一个 external_jar 文件夹,将 test.jar 拷入其中。至此,外部函数的使用环境准备完毕。

    2.7 创建并使用外部函数。

    (1)启动数据库服务器 dmserver,启动 DM 管理工具。

    (2)在 DM 管理工具中,创建外部函数 MY_INT 和 MY_chr,语句如下:

    CREATE OR REPLACE FUNCTION MY_INT(a int, b int) 
    RETURN int
    EXTERNAL '..\dmdbms\bin\external_jar\test.jar' "com.test.package1.test.testAdd" USING java;
    
    CREATE OR REPLACE FUNCTION MY_chr(s varchar) 
    RETURN varchar
    EXTERNAL '..\dmdbms\bin\external_jar\test.jar' "com.test.package1.test.testStr" USING java;
    

    (3)调用 JAVA 外部函数,语句如下:

    select MY_INT(1,2);
    select MY_chr('abc');
    

    (4)查看结果,分别为:

    3
    abc hello
    

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

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

相关文章

PostgreSQL-UDF用户自定义函数-扩展插件

目录 PostgreSQL-UDF用户自定义函数-扩展插件零、前置条件一、创建 .c 和 .sql 文件创建.c文件创建.sql文件 二、创建 .control 和 Makefile 文件创建 .control 文件创建 Makefile 文件 三、编译 & 链接四、psql&#xff08;或者其他PG backend&#xff09;中创建扩展 Post…

illustrator-形状模式-路径查找器-路径偏移-扩展

文章目录 1.形状模式1.1.联集&#xff1a;形状相加1.2.减去顶层&#xff1a;形状减去共同部分1.3.交集&#xff1a;相同部分1.4.差集&#xff1a;形状不同部分 2.路径查找器2.1.分割2.2.修边2.3.合并2.4.裁剪2.5.轮廓2.6.减去后方对象 3.路径偏移4.扩展外观 打开路径查找器快捷…

吃雪糕也能涨知识了!猿辅导携手中街1946推出“冷知识冰棍”

为了给孩子们的暑假学习加点“料”&#xff0c;猿辅导近日脑洞大开&#xff0c;和中街1946携手推出了“冷知识冰棍”&#xff0c;以数学、英语、语文、科学4个科目为外包装&#xff0c;分别对应草莓山楂、青提菠萝、茉莉蓝莓和蜜桃乌龙等4种口味&#xff0c;为孩子们开启了夏日…

在 SwiftUI 中创建一个环形 Slider

文章目录 前言初始化环形轮廓将进度值和拇指位置绑定添加触摸手势为不同的坐标值设置滑块位置总结 前言 Slider 控件是一种允许用户从一系列值中选择一个值的 UI 控件。在 SwiftUI 中&#xff0c;它通常呈现为直线上的拇指选择器。有时将这种类型的选择器呈现为一个圆圈&#…

centos7、ky10_server(arm版、x86版)将程序做成系统服务

前提条件 提供启动脚本、停止脚本 启动脚本 生成app启动脚本 touch app_start.sh cat > app_start.sh << EOF chmod -R 777 /home/zenglg/appcd /home/zenglg/app/apache-tomcat/bin./startup.sh EOF 停止脚本 生成app.停止脚本 touch app_stop.sh cat > app_sto…

ssm学校运动会信息管理系统源码和论文

ssm学校运动会信息管理系统027 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 在当今社会上&#xff0c;体育运动越来越普及&#xff0c;参与运动会的人越来越多&#xff0c;但是目前对运动会信息管理还…

常见的Web安全漏洞有哪些,Web安全漏洞常用测试方法介绍

Web安全漏洞是指在Web应用程序中存在的可能被攻击者利用的漏洞&#xff0c;正确认识和了解这些漏洞对于Web应用程序的开发和测试至关重要。 一、常见的Web安全漏洞类型&#xff1a; 1、跨站脚本攻击(Cross-Site Scripting&#xff0c;XSS)&#xff1a;攻击者通过向Web页面注入…

C语言之extern “C“详解与使用方法

前言 在你工作过的系统里&#xff0c;不知能否看到类似下面的代码。 这好像没有什么问题&#xff0c;你应该还会想&#xff1a;“嗯⋯是啊&#xff0c;我们的代码都是这样写的&#xff0c;从来没有因此碰到过什么麻烦啊&#xff5e;”。 你说的没错&#xff0c;如果你的头文件…

如何使用Redis实现附近商家查询

导读 在日常生活中&#xff0c;我们经常能看见查询附近商家的功能。 常见的场景有&#xff0c;比如你在点外卖的时候&#xff0c;就可能需要按照距离查询附近几百米或者几公里的商家。 本文将介绍如何使用Redis实现按照距离查询附近商户的功能&#xff0c;并以SpringBoot项目…

偷偷告诉你,线上便宜的卡你就得忍受这些毛病!

很多人都觉得线上的流量卡资费便宜&#xff0c;都想随手申请一张&#xff0c;在这里&#xff0c;小编偷偷的告诉大家一下&#xff0c;线上的流量卡资费虽然便宜&#xff0c;但是缺点也有不少&#xff0c;看完你能接受吗&#xff1f; ​ 我们先说一说线上流量卡的优势&#xff1…

如何自定义IIS的页面

到C:\inetpub\wwwroot 文件夹下面有一个 iisstart.htm文件 修改它内容如下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns"http://www.w3.org/1999/xhtml&…

没有放入回收站的文件如何找回?这个方法可以帮你

在我们平常使用电脑时&#xff0c;经常需要删除一些文件或文件夹。通常情况下&#xff0c;这些文件会被移动到回收站&#xff0c;以便我们在需要时可以轻松恢复。然而&#xff0c;有时候我们希望直接永久删除文件&#xff0c;而不经过回收站。不过&#xff0c;在使用这些方法之…

九耶丨阁瑞钛伦特-Spring boot与Spring cloud 之间的关系

Spring Boot和Spring Cloud是两个相互关联的项目&#xff0c;它们可以一起使用来构建微服务架构。 Spring Boot是一个用于简化Spring应用程序开发的框架&#xff0c;它提供了自动配置、快速开发的特性&#xff0c;使得开发人员可以更加轻松地创建独立的、生产级别的Spring应用程…

Azure Bastion的简单使用

什么是Azure Bastion Azure Bastion 是一个提供安全远程连接到 Azure 虚拟机&#xff08;VM&#xff09;的服务。传统上&#xff0c;访问 VM 需要使用公共 IP 或者设立 VPN 连接&#xff0c;这可能存在一些安全风险。Azure Bastion 提供了一种更安全的方式&#xff0c;它是一个…

SB-B300、CKN1262、CKN55160楔块式单向离合器

SB-A130 S8-8130 SB-A150 SB-B150 SB-B180 SB-B180 SB-B200 SB-B200 SB-B250 SB-B250 SB-B300 SB-B300 CKN1262 CKN1568 CKN2075 CKN2590 CKN30100 CKN35110 CKN40125 CKN45130 CKN40150 CKN55160 CKN60170 CKN70190 CKN80210 CKN90230 CKN系列为楔块…

jmeter实用随机字符串常用变量 生成指定位数汇总

前言 在日常接口测试、压力测试时&#xff0c;我们需要生成大量的随机变量。例如&#xff1a;姓名、手机号、随机字符串等。这时候使用Jmeter内置的一些方法的随机生成变量&#xff0c;便成了解决问题的一种方式。 一、姓名随机生成 1.引入代码 ${__RandomString(1,赵钱孙李…

【Java转Go】快速上手学习笔记(三)之基础篇二

【Java转Go】快速上手学习笔记&#xff08;二&#xff09;之基础篇一 了解了基本语法、基本数据类型这些使用&#xff0c;接下来我们来讲数组、切片、值传递、引用传递、指针类型、函数、map、结构体。 目录 数组和切片值传递、引用传递指针类型defer延迟执行函数map结构体匿名…

历时数月钻研推流/对比各种流媒体服务程序/PK总结

1 前言 大量测试下来&#xff0c;网页显示视频流实时性从高到低依次是 webrtc > ws-flv > flv > hls。播放器打开rtsp/rtmp视频流实时性由具体的播放器控制&#xff0c;比如缓存大小和缓存时间&#xff0c;是否音视频同步等。由于flv拉流同源地址最大支持6路同时播放…

docker-php扩展

生成扩展骨架 环境&#xff1a;docker-compose、php74 1.本地要有一份 php-src git clone https://github.com/php/php-src.git cd php-src git checkout PHP-7.4.52.\www\php-src\ext可以看到有一个 ext_skel.php 文件 3.通过ext_skel.php脚本创建了一个hello扩展&#xf…

不用+号算加法(位运算实现)

最近在LeetCode上刷题看到一道非常有意思的题&#xff0c;如何不用号算加法&#xff1f;我觉得挺有意思的故而分享给大家。 在不能使用 号的情况下其实很容易想到运用位运算去解决问题&#xff0c;也就是用二进制去表示十进制加法的逻辑。所以我们可以先拆分十进制加法来帮助理…