KingbaseES生成动态SQL
1. 动态SQL
动态SQL在程序启动时会根据输入参数替换相应变量。使用动态SQL可以创建更强大和灵活的应用程序,但在编译时SQL语句的全文不确定,因此运行时编译会牺牲一些性能。动态SQL可以是代码或SQL语句的一部分,动态部分要么由开发人员输入,要么由程序本身创建。
1.1 动态SQL使用场景
在PL/SQL函数或过程中有时需要生成动态命令,因为命令涉及不同表或数据类型,仅在运行时才能确定具体对象或值。这时比较适合使用动态SQL。
另外,在特定情况下,如果静态SQL语句无法执行,或者您真的不知道函数或过程要执行的确切SQL语句,那么您必须使用动态SQL。
1.2 动态SQL VS 静态SQL
| 静态SQL | 动态SQL |
|---|---|
| SQL语句在编译时编译 | SQL语句在运行时编译 |
| SQL语句在编译时进行解析,有效性检查表、视图和过程。编译时优化并生成应用程序执行计划 | SQL语句在运行时进行编译解析SQL语句,有效性检查表、视图和过程,优化并生成应用程序执行计划 |
| 性能好,速度快 | 与静态SQL相比较性能不好 |
| 不够灵活 | 非常灵活 |
2. 生成动态SQL
共有三种方式实现动态SQL。使用format函数,使用quote_ident 和 quote_literal函数,使用连接操作符||。
注意:构建查询时插入的动态值需要仔细处理,因为可能需要包含引号。
2.1 使用format函数
首先我们介绍下format函数的形式参数:
%s s格式化参数值作为简单字符串. %I I 处理参数值作为SQL 标识符,有必要增加双引号. %L L 引用参数作为SQL字面值.
这里先要区分两个概念:SQL标识符和SQL字面值。
SQL标识符表示数据库名称、表名、索引名、schema名、约束名、游标名、触发器、列、视图名称。在动态SQL中,I%会按照SQL标识符进行解析。
SQL字面值表示显示值,数值、字符、字符串、布尔值,不代表SQL标识符。有不同类型的字面值:
| 类型 | 举例 |
|---|---|
| 字符串 String | ‘Hello! everyone’ |
| 整数 Integer | 45, 78, +89 , -465,6E5 |
| 数值 Decimal | 45.56 |
| 日期 DateTime | ‘5/20/2020’ , TIMESTAMP ‘2020-05-20 12:01:01’; |
| 字符 Character | A’ ‘%’ ‘9’ ’ ’ ‘z’ ‘(’ |
| 布尔 Boolean | true, false, null |
下面举例说明:
test=# SELECT format('Hello! Welcome to my %s!', 'Blog') as msg;
msg
----------------------------
Hello! Welcome to my Blog!
(1 行记录)
test=# SELECT format('%s! Welcome to my %s! - %s','Hi','Blog','Ourtechroom') as msg;
msg
---------------------------------------
Hi! Welcome to my Blog! - Ourtechroom
(1 行记录)
test=# SELECT format('INSERT INTO %I VALUES(%L)', 'tbl_test', 'test');
format
-------------------------------------
INSERT INTO tbl_test VALUES('test')
(1 行记录)
2.2 使用quote_indent 函数
select quote_ident('Hello World'); // "Hello World" 字面量增加引号
select quote_ident('mytable'); // mytable 表名称自动去掉引号
除此之外还有几个类似函数。 QUOTE_LITERAL(string text), QUOTE_LITERAL(value anyelement), QUOTE_NULLABLE(value anyelement);
QUOTE_LITERAL函数返回值自动增加引号。QUOTE_NULLABLE对于非空参数增加引号,否则返回null。
2.3 使用连接操作符||
query := 'SELECT score FROM stu_temp WHERE name='''
|| name
|| '''';
这种方式对于需要转义单引号比较麻烦,且容易造成SQL注入。
3. 总结
本文介绍三种方式实现动态SQL语句,并通过示例对比不同方式的差异。相比使用format方式更简单高效。
KingbaseES生成动态SQL的更多相关文章
- 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
原文链接:http://www.cnblogs.com/quanyongan/p/3152290.html 最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 ...
- DB2存储过程实现查询表数据,生成动态SQL,并执行
一.动态执行SQL PREPARE S1 FROM 'delete from test'; EXECUTE S1; 二.使用游标 DECLARE V_CURSOR CURSOR FOR SELECT ...
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
最近在使用Hibernate4中,发现两个很有奥秘的注解 @DynamicInsert 和 @DynamicUpdate 如果是在配置文件的话那就是dynamic -insert 和 dynamic- ...
- 使用mybatis的动态sql解析能力生成sql
需求: 计算平台,有很多表,打算提供一个基于sql的服务接口, sql不能完全在配置页面写死, 要能根据参数不同执行不同的语义,防止sql个数爆炸 把mybatis原码down下来, 改造一下测试用例 ...
- spring boot-mybatis三种动态sql(5)
脚本sql XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现.适用于xml配置转换到注解配置 @Select(" ...
- mybatis的注解开发之三种动态sql
脚本sql XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现.适用于xml配置转换到注解配置 @Select(" ...
- spring boot(8)-mybatis三种动态sql
脚本sql XML配置方式的动态SQL我就不讲了,有兴趣可以自己了解,下面是用<script>的方式把它照搬过来,用注解来实现.适用于xml配置转换到注解配置 @Select(" ...
- Spring Boot (10) mybatis三种动态sql
脚本SQL xml配置方式见mybatis讲解,下面是用<script>的方式把它照搬过来,用注解来实现.适于xml配置转换到注解配置 @Select("<script&g ...
- SpringBoot+MyBatis的动态SQL、使用动态SQL时List传值错误解决方案
目录 实现动态SQL的四种方式: 1.XML配置 2.脚本SQL 3.在方法中构建SQL 4.结构化SQL 关于动态SQL的List传值错误问题 1.错误代码 2.解决错误 实现动态SQL的四种方式: ...
- MySQL存储过程动态SQL语句的生成
用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...
随机推荐
- 【Unity3D】UI Toolkit自定义元素
1 前言 UI Toolkit 支持通过继承 VisualElement 实现自定义元素,便于通过脚本控制元素.另外,UI Toolkit 也支持将一个容器及其所有子元素作为一个模板,便于通过脚本 ...
- 【Unity3D】基于模板测试和顶点膨胀的描边方法
1 前言 选中物体描边特效 中介绍了基于模板纹理模糊膨胀的描边方法,该方法实现了软描边,效果较好,但是为了得到模糊纹理,对屏幕像素进行了多次渲染,效率欠佳.本文将介绍另一种描边方法:基于模板测试和 ...
- P3879 [TJOI2010] 阅读理解(水题)
[TJOI2010] 阅读理解 题目描述 英语老师留了 N 篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过. 输入格式 第一 ...
- sql题目---day39
# 1.查询所有的课程的名称以及对应的任课老师姓名 #where select teacher.tname,course.cname from teacher,course where course. ...
- python文件加锁模块之fcntl
# 示例 import fcntl with open('./test.txt', 'w') as f: fcntl.flock(f, fcntl.LOCK_EX) # 对文件加锁,除加锁进程外其它进 ...
- 【Azure Redis】Azure Redis添加了内部虚拟网络后,其他区域的主机通过虚拟网络对等互连访问失败
问题描述 跨区域无法访问Azure Redis服务, Redis 启用了Network并设置在一个VNET中,现在客户端部署在另一个区域数据中心中,两个数据中心区域使用VNET Peer(对等互连)访 ...
- 【Azure 媒体服务】使用编码预设文件(Preset.json)来自定义编码任务 -- 创建视频缩略图
问题描述 在Azure门户上创建Transform Encoding时候,只能选择 Built-in Preset 编码方式(如:H265ContentAwareEncoding) 在创建编码任务时, ...
- Nebula Graph 源码解读系列 | Vol.02 详解 Validator
整体架构 Nebula Graph Query Engine 主要分为四个模块,分别是 Parser.Validator.Optimizer 和 Executor. Parser 完成对语句的词法语法 ...
- [C++逆向] 7 变量在内存中的位置和访问方式
目录 全局变量和局部变量的区别 局部静态变量 有意思的 堆变量 变量类型 作用域 可访问 全局变量 进程作用域 整个进程可访问 静态变量 文件作用域 当前代码文件可访问 局部变量 函数作用域 函数内可 ...
- liunx 进阶技术
以下命令非学习阶段常用,在工作设汲到用liunx操作的时候以下必然要用,所以记录整理一下 关掉服务器所有java程序使用命令 pkill java 查看当前运行java服务 ps -ef | grep ...