如何用 esProc 补充数据库 SQL 的缺失能力
某些数据库 SQL 缺失必要的能力,通常要编写大段的代码,才能间接实现类似的功能,有些情况甚至要改用存储过程,连结构都变了。常见的比如:生成时间序列、保持分组子集、动态行列转换、自然序号、相对位置、按序列和集合生成多条记录、累积计算、条件分组、跨库计算、集合计算、序列计算、自关联结构、递归计算、对齐式关联等。用下面几个例子快速感受一下。
生成时间序列:某库表的 Time 字段是时间,时间的间隔有时大于 1 分钟。
| Time | Value |
| 10:10:05 | 3 |
| 10:11:06 | 4 |
| 10:13:13 | 5 |
| 10:13:19 | 9 |
| 10:13:32 | 8 |
| 10:14:35 | 2 |
现在要将数据每分钟分成一个窗口,补上缺失的窗口,对每个窗口统计 4 个值:前一个窗口的最后一条 start_value;本窗口的最后一条;本窗口的最小值;本窗口的最大值。第一分钟的 start_value 用本窗口的第一条记录;如果缺少某窗口的数据,则用前一个窗口的最后一条代替。
| start | end | start_value | end_value | min | max |
| 10:10:00 | 10:11:00 | 3 | 3 | 3 | 3 |
| 10:11:00 | 10:12:00 | 3 | 4 | 4 | 4 |
| 10:12:00 | 10:13:00 | 4 | 4 | 4 | 4 |
| 10:13:00 | 10:14:00 | 4 | 8 | 5 | 9 |
| 10:14:00 | 10:15:00 | 8 | 2 | 2 | 2 |
很多数据库的 SQL 没有方便的方法生成月份序列,很多数据库要用多层嵌套查询 + 多个窗口函数才能间接实现。
保持分组子集:某表存储多个账号在多个日期发生的事件。
| Row | Account Number | Date |
| 1 | 1001 | 2011-01-10 |
| 2 | 1001 | 2011-02-01 |
| 3 | 1001 | 2011-02-20 |
| 4 | 1001 | 2011-02-22 |
| 5 | 2001 | 2011-04-11 |
| 6 | 2001 | 2012-01-01 |
| 7 | 2001 | 2012-01-30 |
| 8 | 2001 | 2012-02-09 |
现在要找出每个账号下符合条件的一对事件,分别是:日期最早的事件 a、距 a 事件 30 天以上的事件中日期最早的事件 b。
| Row | Account Number | Date |
| 1 | 1001 | 2011-01-10 |
| 3 | 1001 | 2011-02-20 |
| 5 | 2001 | 2011-04-11 |
| 6 | 2001 | 2012-01-01 |
SQL 分组后必须立刻汇总,很难按条件 b 筛选记录,只能用 join 语句配合多个 CTE 子句间接实现。
动态行列转换:某库表记录了不同产品每个月的销售额,其中产品的值未知。
| product | month | amount |
| AA | 1 | 100 |
| AA | 1 | 150 |
| AA | 2 | 200 |
| AA | 2 | 120 |
| BB | 2 | 180 |
| BB | 2 | 220 |
| CC | 3 | 80 |
现在要对产品、月份分组,对销售额求和,再将产品由行转列。
| month | AA | BB | CC |
| 1 | 250 | ||
| 2 | 320 | 400 | |
| 3 | 80 | ||
某些数据库的 SQL 缺失动态行列转换能力,行转列时必须写出列名,很多数据库只能改用存储过程。
esProc SPL 内置丰富的计算类库,可以补充这些数据库 SQL 缺失的能力,比如上面 3 个例子:
"https://c.raqsoft.com.cn/article/1742353802112"
“@从 SQL 到 SPL:计算组内符合条件的一对最小值 - 乾学院”
“从 SQL 到 SPL:Create columns from distinct values of a column - 乾学院”
下面,我们就来尝试一下如何将 esProc 集成到应用中。
先下载 esProc,推荐标准版:集算器 产品下载 | 报表加速器下载-半结构化计算软件下载
下载并安装相应的版本。
安完后,试一下 esProc IDE 是否可以正常访问数据库。先把数据库的 JDBC Driver 放到目录 "[安装目录]\common\jdbc",这是 esProc 的类路径之一。比如 mySQL 的 JDBC:

打开 esProc IDE,找到菜单 "Tool->Connect to Data Source",新建 JDBC 数据源,填入具体数据库的连接信息。下面是一个 mySQL 的数据源:

返回到数据源界面,试着连接数据源,跨库运算时可以同时连接多个数据源。如果数据源名变成粉色,说明配置成功。

在 IDE 中新建脚本,写 SPL 语句,连接 mysql 数据库,加载第 1 个例子的数据:
=connect("mysql").query@x("select * from main")
按 ctrl-F9 执行,可以在 IDE 右边看到执行结果,以数据表的形式呈现,这对调试 SPL 代码很方便。

加载数据正常后,就可以写正式的 SPL 代码了,第 1 个例子:
| A | |
| 1 | =connect("mysql").query@x("select * from main where time>? and time<=?",arg1,arg2) |
| 2 | =A1.run(Time=time@m(Time)) |
| 3 | =list=periods@s(A2.min(Time),A2.max(Time),60) |
| 4 | =A2.align@a(list,Time) |
| 5 | =A4.new(list(#):start, elapse@s(start,60):end, sv=ifn(end_value[-1],~.Value):start_value, ifn(~.m(-1).Value, sv):end_value, ifn(~.min(Value),sv):min, ifn(~.max(Value),sv):max) |
先用参数过滤;再将时间改为整分钟数;生成连续分钟的时间序列;将数据按时间序列对齐,每组数据对应一分钟的窗口;按要求用每组数据生成一条新记录。
把上面脚本保存在某个目录中,比如 D:\data\procMain.splx,运行后可以看到结果:

第 2 个例子:
| A | |
| 1 | =connect("mysql").query@x("select * from ventas") |
| 2 | =A1.group(#2) |
| 3 | =A2.conj(~1 | ~.select@1((#3 - A2.~1.#3)>30)) |
加载数据;按 2 个字段分组,但不汇总;取每组第 1 条,再筛选出距第 1 条 30 天以上的记录,也取第 1 条;合并这 2 条记录,最后合并各组的处理结果。
保存成 D:\data\proc2.splx,执行后看结果:

第 3 个例子:
=connect("mysql").query@x("select * from ventas").pivot@s(month;product,sum(amount))
加载数据后动态转置,执行结果:

在 IDE 中调试无误后,就可以把 esProc 集成到 Java 环境中了。
从目录 "[安装目录]\esProc\lib" 下找到 esProc JDBC 相关的 jar 包:esproc-bin-xxxx.jar、icu4j_60.3.jar。

将这两个 jar 包部署到 Java 开发环境的类路径下。
再从目录 "[安装目录]\esProc\config" 下找到 esProc 配置文件 raqsoftConfig.xml,同样部署到 Java 开发环境的类路径下。

配置文件中要改的配置项是 mainPath,这表示脚本等文件的默认路径。注意数据源的信息也在配置文件中。
接下来,就可以编写 Java 代码,通过 esProc JDBC 调用 SPL 脚本了,例子 1:
Class.forName("com.esproc.jdbc.InternalDriver");
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareCall("call procMain(?,?)");
st.setTime(1,Time.valueOf("10:00:00"));
st.setTime(2,Time.valueOf("11:00:00"));
ResultSet rs = st.executeQuery();
可以看到,调用 SPL 脚本的过程和调用存储过程是一样的。计算后结果如下:

脚本文件不是必须的,可以把 SPL 脚本转为 SPL 代码,像 SQL 那样嵌入 Java。先在 IDE 中打开例子 2 的脚本文件,选中有代码的单元格 A1-A3,再点击菜单 "Edit->Copy->Code copy",这样就把多行多列的网格代码转成了单行的 SPL 代码,暂存在粘贴板里。

将转换后的 SPL 代码复制到 Java 代码中
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareStatement("==connect(\"mysql\").query@x(\"select * from ventas\")\n=A1.group(#2) \n=A2.conj(~1 | ~.select@1((#3 - A2.~1.#3)>30))");
ResultSet rs = st.executeQuery();
可以看到,Java调用SPL代码的过程和调用SQL代码一样。运行后可以看到结果:
可以看到,Java调用SPL代码的过程和调用SQL代码一样。运行后可以看到结果:

有些 SPL 代码比较简单,没必要用 esProc IDE 编写调试,那就可以直接写在 Java 里。比如例子 3,直接在 Java 中嵌入 SPL 代码:
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareStatement("=connect(\"mysql\").query@x(\"select * from ventas\").pivot@s(month;product,sum(amount))");
ResultSet rs = st.executeQuery();
执行结果像下面这样:

乾学院上还有很多补充 SQL 缺失能力的例子,开发遇到问题时可以去找找解决办法。
相关文章:
如何用 esProc 补充数据库 SQL 的缺失能力
某些数据库 SQL 缺失必要的能力,通常要编写大段的代码,才能间接实现类似的功能,有些情况甚至要改用存储过程,连结构都变了。常见的比如:生成时间序列、保持分组子集、动态行列转换、自然序号、相对位置、按序列和集合生…...
晶晨线刷工具下载及易错点说明:Key文件配置错误/mac剩余数为0解决方法
晶晨线刷工具下载及易错点说明:Key文件配置错误/mac剩余数为0解决方法 各种版本晶晨线刷工具下载: 晶晨线刷工具易出错点故障解决方法: 1、晶晨线刷工具加载固件的时候提示mac红字且剩余数为0的解决办法 很多同学可能会与遇到加…...
论文阅读:Invertible Grayscale
这是一篇 ACM Transactions on Graphic 上的文章,这篇文章中介绍的应用还挺有意思的,关于可逆的图像灰度化。 Abstract 一旦彩色图像被转换为灰度图像,人们普遍认为,即使采用最先进的彩色化方法,原始颜色也无法完全恢…...
linux下使用php修改php.ini的session.save_path无效的解决办法
linux下安装php的组合还是php-fpm和nginx,其实已经安装好了,网站已经能够跑起来了,但是遇到后台登录的时候验证码一直不对,看了下报错,session无法存储,于是新增了一个phpinfo文件,使用web查看下…...
关于ResNet和FPN的一份介绍
在这篇文章中我将介绍ResNet和FPN这两个深度学习中重要的技术。 一、ResNet-50/101 首先我们先来看ResNet技术: 1.1 概述 ResNet技术是基于残差学习,引入Bottleneck技术以及Shortcut Connection技术,而去解决神经网络中的退化问题。 1.2…...
以技术的形式实现发票真伪的快速查验-Android发票查验接口
对于企业而言,假票入账不仅可能导致企业财务损失,更会引发一系列法律风险,因此精准、高效的发票查验服务成为了企业运营不可或缺的支持。发票验真服务接口,正是一款能满足这些需求,助力企业摆脱繁琐流程、提升工作效率…...
Python实现贪吃蛇三
上篇文章Python实现贪吃蛇一,实现了一个贪吃蛇的基础版本。后面第二篇文章Python实现贪吃蛇二修改了一些不足,但最近发现还有两点需要优化: 1、生成食物的时候有概率和记分牌重合 2、游戏缺少暂停功能 先看生成食物的时候有概率和记分牌重合的…...
Docker 中多个容器之间的通信
在 Docker 中,多个容器之间的通信可以通过以下几种主要方式实现,具体选择取决于网络需求、隔离性及管理复杂度: 一、自定义 Bridge 网络(推荐) 通过创建自定义的 Docker 网络,容器可以加入同一网络并通过容…...
AI大模型学习九:Sealos cloud+k8s云操作系统私有化一键安装脚本部署完美教程
一、说明 Sealos是一款基于Kubernetes(K8s)的云操作系统发行版,它将K8s以及常见的分布式应用如Docker、Dashboard、Ingress等进行了集成和封装,使得用户可以在不深入了解复杂的K8s底层原理的情况下,快速搭建起一个…...
详解关于VS配置好Qt环境之后但无法打开ui界面
目录 找到Qt安装目录中designer.exe的路径 找到vs中的解决方案资源管理器 右键ui文件,找到打开方式 点击添加 然后把前面designer.exe的路径填到程序栏中,点击确定 然后设置为默认值,并点击确定 当在vs中配置好Qt环境之后,但…...
Python Cookbook-6.5 继承的替代方案——自动托管
任务 你需要从某个类或者类型继承,但是需要对继承做一些调整。比如,需要选择性地隐藏某些基类的方法,而继承并不能做到这一点。 解决方案 继承是很方便的,但它并不是万用良药。比如,它无法让你隐藏基类的方法或者属…...
【深度学习与大模型基础】第9章-条件概率以及条件概率的链式法则
简单理解条件概率 条件概率就是在已知某件事发生的情况下,另一件事发生的概率。用数学符号表示就是: P(A|B) 在B发生的前提下,A发生的概率。 计算机例子:垃圾邮件过滤 假设你写了一个程序来自动判断邮件是否是垃圾邮件…...
STM32-FreeRTOS的详细配置
配置FreeRTOS 原文链接:https://ydamooc.github.io/posts/c9defcd/ 1.1 下载FreeRTOS 打开FreeRTOS官网:https://www.freertos.org/ 点击下载,并且选择"FreeRTOS 202212.01"版本,再点击Download按钮下载官方的资源包…...
行为检测技术指南
以下是行为检测技术的全面技术指南,涵盖核心技术原理、应用场景及发展趋势: 一、核心行为检测技术分类 1. 基于计算机视觉的行为检测 目标检测算法 通过目标定位与分类识别行为,典型算法包括: YOLO系列(YOLOv5/v8):实时性强,适用于视频流中的动作识别(如摔倒、抽烟检…...
视觉自回归图像生成:基于多模态大模型的万字深度梳理
目前利用多模态大模型进行图像生成主要有以下两种形式: LLM作为condtioner:利用MLLM依据用户输入的text prompt来生成条件信息,条件信息被注入到下游生成模型进行更精细化的生成控制。这种形式通常需要外接一个额外专门的多模态生成模型&…...
openssh离线一键升级脚本分享(含安装包)
查看当前的版本 [rootmyoracle ~]#ssh -V相关安装包下载地址 openssh下载地址:http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssl下载地址:https://www.openssl.org/source/zlib下载地址:http://www.zlib.net/今天演示从7.4升级…...
音视频之H.265/HEVC预测编码
H.265/HEVC系列文章: 1、音视频之H.265/HEVC编码框架及编码视频格式 2、音视频之H.265码流分析及解析 3、音视频之H.265/HEVC预测编码 预测编码是视频编码中的核心技术之一。对于视频信号来说,一幅图像内邻近像素之间有着较强的空间相关性,相邻图像之…...
Python异步编程入门:Async/Await实战详解
引言 在当今高并发的应用场景下,传统的同步编程模式逐渐暴露出性能瓶颈。Python通过asyncio模块和async/await语法为开发者提供了原生的异步编程支持。本文将手把手带你理解异步编程的核心概念,并通过实际代码案例演示如何用异步爬虫提升10倍效率&#…...
设计模式每日硬核训练 Day 13:桥接模式(Bridge Pattern)完整讲解与实战应用
🔄 回顾 Day 12:装饰器模式小结 在 Day 12 中,我们学习了装饰器模式(Decorator Pattern): 强调在不改变原类结构的前提下,动态为对象增强功能。通过“包装对象”实现运行时组合,支…...
库洛游戏一面+二面
目录 一面 1. ArrayList和LinkedList的区别,就是我在插入和删除的时候他们在时间复杂度上有什么区别 2. hashmap在java的底层是怎么实现的 3. 红黑树的实现原理 4. 红黑树的特点 5. 为什么红黑树比链表查询速度快 6. 在java中字符串的操作方式有几种 7. Stri…...
前端面试-Vue篇
核心概念 Vue 3的响应式原理与Vue 2有何本质区别?Vue中虚拟DOM的diff算法优化策略有哪些?Vue组件间通信方式有哪些?适用场景分别是什么?Vue的生命周期钩子在Composition API中如何替代?Vue的模板编译过程是怎样的&…...
XSS攻击(反射型、存储型、dom型、PDF、SWF、SVG)
一、XSS攻击是什么 XSS是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行,从而可以达到攻击者盗取用户信息或其他侵犯用户安全隐私的目的。 二、XSS分类 反射型XSS 常见情况是…...
C复习(主要复习)
指针和数组 指针数组是一个数组,数组的每个元素都是指针。它适用于需要存储多个指针的场景,如字符串数组。数组指针是一个指针,指向一个数组。它适用于需要传递整个数组给函数或处理多维数组的场景。 函数指针:函数指针的定义需要…...
Python及C++中的集合
1. Python 中的集合(set) 1.1 特性 无序性:集合中的元素没有顺序,不能通过索引访问。唯一性:集合中的元素不能重复,如果尝试添加重复的元素,集合会自动忽略。可变性:集合是可变的&…...
Ubuntu24.04搭建ESP8266_RTOS_SDK V3.4开发环境
【本文发布于https://blog.csdn.net/Stack_/article/details/147194686,未经允许不得转载,转载须注明出处】 需要有Linux使用基础,自行准备 1、VM17 Pro (自行搜索教程安装) 2、ubuntu-24.04-desktop-amd64 ࿰…...
数据仓库分层存储设计:平衡存储成本与查询效率
数据仓库分层存储不仅是一个技术问题,更是一种艺术:如何在有限的资源下,让数据既能快速响应查询,又能以最低的成本存储? 目录 一、什么是数据仓库分层存储? 二、分层存储的体系架构 1. 数据源层(ODS,Operational Data Store) 2. 数据仓库层(DW,Data Warehouse)…...
matlab求和∑函数方程编程?
matlab求和∑函数方程编程? 一 题目:求下列函数方程式的和 二:代码如下: >> sum_result 0; % 初始化求和变量 for x 1:10 % 设…...
基于Java+MySQL实现的(Web)科研资讯推送系统
科研资讯推送系统 技术选型 核心框架:SpringBoot 数据库层:springdatajpa 安全框架:Shiro 数据库连接池:Druid 缓存:Ehcache 部署 阿里云学生机:ecs.n4.small Tomcat:9.0 JDK:1.8 数据库:MySQL8.0 操作系统:CentOS…...
PHP弱类型hash比较缺陷
目录 0x00 漏洞原因 0x01 利用方法 0x02 [BJDCTF2020]Easy MD5 1 利用md5($password,true)实现SQL注入 PHP md5弱类型比较 数组绕过 0x00 漏洞原因 1、在进行比较的时候,会先将两边的变量类型转化成相同的,再进行比较 2、0e在比较的时候会将其认…...
asm汇编源代码之-汉字点阵字库显示程序源代码下载
汉字点阵字库显示程序 源代码下载 文本模式下显示16x16点阵汉字库内容的程序(标准16x16字库需要使用CHGHZK转换过后才能使用本程序正常显示) 本程序需要调用file.asm和string.asm中的子程序,所以连接时需要把它们连接进来,如下 C:\> tlink showhzk file string 调用参…...
