概述 :在DBA的日常工作中,经常遇到一些需要基于数据库当前状态的实用程序查询的实例。比如一个逻辑复制的目标表,主键ID列与生成数据的序列不同步,这将导致插入新行是,会有主键冲突。要纠正这个问题,需要设置序列可以生成的值,超过表中当前最大值。

解决此类问题可以使用动态DDL,虽然SQL 中的数据定义语言(DDL) 本身是非动态的,因为DDL需要有严格的解析规则,而且其中的子查询预定义的数据类型、表结构,以及基于已知关联列。

下面的案例,可以让 SQL语句随心所欲地执行动态 DDL,而不必每次都手动编写这些查询。

一、改变序列重启值的解决方案

希望通过查询显式地为序列提供RESTART值,重置一个序列,使其从它所关联的表的当前最大值之后开始。预想中,使用简单直接的DDL语句:

ALTER SEQUENCE tablename_id_seq RESTART (SELECT max(id)+1 FROM tablename);
ERROR: syntax error at or near "(", at character 38
STATEMENT: ALTER SEQUENCE tablename_id_seq RESTART (SELECT max(id) + 1 FROM tablename);

正如所看到的,KingbaseE语法不支持这种方法,因为这里需要的是实际值,而不是子查询。

1、使用ksql的变量替换

使用ksql变量,首先选择一个变量的值,然后将这个值替换到表达式中。

-- 使用\gset设置一个带有查询结果的变量

SELECT max(id) + 1 as id_max from tablename
\gset
-- substitute the variable in a new query
ALTER SEQUENCE tablename _id_seq RESTART :id_max ;

在实例中,使用\gset命令来得到max(id)+1的结果,并将其存储在会话中,供以后使用。然后使用:id_max语法将该变量插入到SQL语句中,将其直接传递给服务器。

2、使用ksql的 \gexec 命令

使用ksql进行动态SQL的另一种方法,是设计一个查询SELECT语句,返回希望运行的语句,然后使用\gexec命令执行。

SELECT 'ALTER SEQUENCE tablename_id_seq RESTART ' || max(id) + 1 as query FROM tablename;

\gexec query

ALTER SEQUENCE tablename_id_seq RESTART 100001

ALTER SEQUENCE

与变量替换相比,这种方法的一个优点是,它可以处理更复杂的语句和多个返回值,因此可以基于任意条件设计查询语句,并生成多个SQL语句;第一个方法实现仅限于每次返回单个行的查询。在使用\gexec对服务器执行SQL语句之前,这还可以预览将要运行的SQL语句,因此提供一定程度的安全性。

二、非ksql的动态SQL

ksql具有处理动态SQL的功能,但如何在第三方应用中,实现动态SQL的功能。现在使用基本类似的方法,编写sql语句块来生成查询,然后执行返回的SQL语句。这些方法与上面的ksql部分中的方法大致相关,因此适用于单个或多个动态语句。

1、匿名块

要使用服务器端动态SQL,我们需要使用format函数构造查询,并执行底层文本,就像我们自己发出底层查询一样。

BEGIN
EXECUTE format('ALTER SEQUENCE tablename_id_seq RESTART %s', (SELECT max(id) + 1 FROM tablename));
END;

2、创建函数 exec()

与匿名块的功能几乎相同,我们也可以创建一个简单的用户函数,简单地调用它的输入参数EXECUTE。

CREATE OR REPLACE FUNCTION exec(raw_query text) RETURNS text AS
BEGIN
EXECUTE raw_query;
RETURN raw_query;
END;
SELECT exec(format('ALTER SEQUENCE tablename_id_seq RESTART %s', (SELECT max(id) + 1 FROM tablename)));

函数方法基本上只是将查询移动到传入的参数中,但它带来更灵活的针对构造的查询列表,在SQL语句中调用此函数,可以选择依次运行每个 SQL。

限制

这些方法对动态SQL运行的限制,在显式事务块之外,运行的SQL命令受到限制。如果想在所有已知索引上运行REINDEX CONCURRENTLY,那么使用exec()函数为public模式中的所有索引执行REINDEX CONCURRENTLY语句:

SELECT exec(format('REINDEX INDEX CONCURRENTLY %I', relname))
FROM sys_class r
JOIN sys_namespace s ON r.relnamespace = s.oid
WHERE relkind = 'i' AND nspname = 'public' ; ERROR: REINDEX CONCURRENTLY cannot be executed from a function
CONTEXT: SQL statement "REINDEX INDEX CONCURRENTLY tablename_pkey"
PL/SQL function exec(text) line 3 at EXECUTE

从这里看到,由于REINDEX CONCURRENTLY需要管理自己的事务状态,因此它不能作为函数运行;在 KingbaseES 中,函数的内在事务运行时,是以函数的SQL语句完全成功或完全失败。

试一试命令 \gexec

SELECT format('REINDEX INDEX CONCURRENTLY %I', relname)
FROM sys_class r
JOIN sys_namespace s ON r.relnamespace = s.oid
WHERE relkind = 'i' AND nspname = 'public' \gexec

  

由于\gexec处理是由ksql完成的,因此生成的语句独立运行。

巧用KingbaseES中的动态DDL的更多相关文章

  1. 在Oracle中执行动态SQL的几种方法

    转载:在Oracle中执行动态SQL的几种方法 以下为内容留存: 在Oracle中执行动态SQL的几种方法 在一般的sql操作中,sql语句基本上都是固定的,如:SELECT t.empno,t.en ...

  2. 巧用FPGA中资源

    随着FPGA的广泛应用,所含的资源也越来越丰富,从基本的逻辑单元.DSP资源和RAM块,甚至CPU硬核都能集成在一块芯片中.在做FPGA设计时,如果针对FPGA中资源进行HDL代码编写,对设计的资源利 ...

  3. 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap

    × 目录 [1]NodeList [2]HTMLCollection [3]NamedNodeMap[4]注意事项 前面的话 一说起动态集合,多数人可能都有所了解.但是,如果再深入些,有哪些动态集合, ...

  4. Quartz 在 Spring 中如何动态配置时间--转

    原文地址:http://www.iteye.com/topic/399980 在项目中有一个需求,需要灵活配置调度任务时间,并能自由启动或停止调度. 有关调度的实现我就第一就想到了Quartz这个开源 ...

  5. ZBrush中的动态网格该怎么进行运用

    DynaMesh是ZBrush最新的基础模型创建工具,该命令用于基本模型的起稿到中模的制作.使用DynaMesh完全不启用考虑模型的拓扑,可以从一个图形拉扯出整个模型的分支,本文将以一个实例简单介绍Z ...

  6. (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)

    目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...

  7. 使用Java中的动态代理实现数据库连接池

    2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...

  8. Linux中的动态库和静态库(.a/.la/.so/.o)

    Linux中的动态库和静态库(.a/.la/.so/.o) Linux中的动态库和静态库(.a/.la/.so/.o) C/C++程序编译的过程 .o文件(目标文件) 创建atoi.o 使用atoi. ...

  9. iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建

    iOS开发UI篇—在UITableview的应用中使用动态单元格来完成app应用程序管理界面的搭建 一.实现效果 说明:该示例在storyboard中使用动态单元格来完成. 二.实现 1.项目文件结构 ...

随机推荐

  1. JavaWeb的技术体系

    客户端和服务器端的交互 browser/ server(B/S)浏览器/服务器. client/server(C/S)应用/服务器.

  2. 关于C标准库stdarg.h

    看<数据结构(C语言版)>(严蔚敏)时看到p94上面va_list啥的,看不懂了,于是整理一下这一部分的知识. 1/当无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表. i ...

  3. squareline搭档OneOS图形组件之可视化GUI开发

    LVGL+OneOS! LVGL,一款很火的GUI开发库,一个高度可裁剪.低资源占用.界面美观且易用的嵌入式系统图形库.本身并不依赖特定的硬件平台,任何满足LVGL硬件配置要求的微控制器均可运行LVG ...

  4. Hash 哈希表和算法思路详解

    概述 哈希表是一种可以满足快速查找数据结构,时间复杂度接近O(1). 哈希函数是无限集到有限集的映射. 处理数据量大,查找效率要求高时推荐使用hash容器. 问题: 什么情况下考虑使用哈希容器? 常用 ...

  5. Vue 路由懒加载, VueRouter一步完成Vue的路由懒加载 一行代码搞定懒加载

    Vue Router路由配置中的component里面配置即可 1 // 路由懒加载的方式加载组件 2 3 component: () => import('@/views/Detail'), ...

  6. 零基础学Java(8)数组

    数组 数组存储相同类型值的序列. 声明数组 数组是一种数据结构,用来存储同一类型值的集合.通过一个整型下标(index,或称索引)可以访问数组中的每一个值.例如,如果a是一个整型数组,a[i]就是数组 ...

  7. 03 uniapp自定义导航栏的开发

    在我眼里自定义导航分2类: 原生基础上 || 非原生基础上 总结:项目当中能原生就原生,提高性能 区别 uni-app 自带原生导航栏,在pages.json里配置. 原生导航的体验更好,渲染新页面时 ...

  8. Jetpack Compose学习(8)——State及remeber

    原文地址: Jetpack Compose学习(8)--State状态及remeber关键字 - Stars-One的杂货小窝 之前我们使用TextField,使用到了两个关键字remember和mu ...

  9. centos7设置虚拟机静态ip

    转自http://blog.csdn.net/y534560449/article/details/60134301 一.设置VM的NAT方式 1.打开VM->编辑->虚拟网络编辑器-&g ...

  10. Nginx api接口调用配置

    1 # Nginx api接口调用配置 2 3 # 什么是跨域同源? 4 # 同源策略:协议(http.https.wss--)+域名+端口=一个完整的网站 5 # 跨域:当前所在的网站post(ge ...