过程、触发器、用户定义函数和批处理中使用的 EXECUTE IMMEDIATE

EXECUTE IMMEDIATE 语句允许使用文字字符串(在引号中)和变量的组合来构建语句。例如,以下过程包含创建表的 EXECUTE IMMEDIATE 语句。

CREATE PROCEDURE CreateTableProcedure(

IN tablename CHAR(128) )

BEGIN

EXECUTE IMMEDIATE 'CREATE TABLE '

|| tablename

|| '( column1 INT PRIMARY KEY )'

END;

EXECUTE IMMEDIATE 语句可以与返回结果集的查询一起使用。您可将 WITH RESULT SET ON 子句与 EXECUTE IMMEDIATE 语句配合使用,以指示语句返回结果集—缺省行为是语句不返回结果集。指定 WITH RESULT

SET ON 或 WITH RESULT SET OFF 同时影响创建过程时和执行过程时所发生的事件。

请考虑以下过程:

CREATE OR REPLACE PROCEDURE test_result_clause()

BEGIN

EXECUTE IMMEDIATE WITH RESULT SET OFF 'SELECT 1';

END;

当过程定义中不包括 RESULT SET 子句时,数据库服务器将试图确定过程是否生成结果集。在此处,EXECUTE IMMEDIATE 语句指定不生成结果集。因此,数据库服务器定义的过程没有结果集列,并且此过程的 SYSPROCPARM 系统视图中也没有任何行。对此过程的

CALL 执行 DESCRIBE 将不会返回任何结果列。如果嵌入式 SQL 应用程序使用该信息来决定是否要打开游标或执行语句,则其会执行语句,然后返回错误。

作为第二个示例,请考虑上述过程的修改版本:

CREATE OR REPLACE PROCEDURE test_result_clause()

BEGIN

EXECUTE IMMEDIATE WITH RESULT SET ON 'SELECT 1';

END;

在此处,WITH RESULT SET ON 子句将致使此过程的 SYSPROCPARM 系统视图中存在一个行。数据库服务器不知道结果集的外观—因为过程正在使用 EXECUTE IMMEDIATE—但其知道过程将返回结果集,所以数据库服务器在

SYSPROCPARM 中定义一个虚设的结果集列来表示过程的结果集(其名称为 "expression",类型为 SMALLINT)。请注意,仅创建一个虚设的结果集列;使用 EXECUTE IMMEDIATE 语句时,服务器无法确定各结果集的列的数目和类型。因此,请考虑以下稍做修改的示例:

CREATE OR REPLACE PROCEDURE test_result_clause()

BEGIN

EXECUTE IMMEDIATE WITH RESULT SET ON 'SELECT 1, 2, 3';

END;

在此,虽然 SELECT 会返回含有三个列的结果集,但服务器仍然仅在 SYSPROCPARM 系统视图中放置一行。因此,以下查询

SELECT * FROM test_result_clause();

失败并生成 SQLCODE -866,因为运行时的结果集特性与 SYSPROCPARM 中的占位符结果不匹配。

要执行上述查询,您可以显式指定结果集列的名称和类型,如下所示:

SELECT * FROM test_result_clause() WITH (x INTEGER, y INTEGER, z INTEGER);

在执行时,如果指定 WITH RESULT SET ON,数据库服务器处理返回结果集的 EXECUTE IMMEDIATE 语句。但是,如果指定 WITH RESULT SET OFF 或省略该子句,则数据库服务器仍会在已分析的字符串参数中查看第一个语句的类型。如果该语句是 SELECT 语句,则其会返回结果集。因此,在上面的第二个示例中:

CREATE OR REPLACE PROCEDURE test_result_clause()

BEGIN

EXECUTE IMMEDIATE WITH RESULT SET OFF 'SELECT 1';

END;

从 Interactive SQL 中可以成功地调用此过程。但是,如果更改此过程以使其包含批处理,而不是仅包含一个 SELECT 语句:

CREATE OR REPLACE PROCEDURE test_result_clause()

BEGIN

EXECUTE IMMEDIATE WITH RESULT SET OFF

'begin declare v int; set v=1; select v; end';

END;

则对 test_result_clause 过程的 CALL 将会返回错误(SQLCODE -946、SQLSTATE 09W03)。

最后一个示例说明您如何将 SELECT 语句构造为某个过程中的 EXECUTE IMMEDIATE 语句的参数,并使该过程返回结果集。

CREATE PROCEDURE DynamicResult(

IN Columns LONG VARCHAR,

IN TableName CHAR(128),

IN Restriction LONG VARCHAR DEFAULT NULL )

BEGIN

DECLARE Command LONG VARCHAR;

SET Command = 'SELECT ' || Columns || ' FROM ' || TableName;

IF ISNULL( Restriction,'') <> '' THEN

SET Command = Command || ' WHERE ' || Restriction;

END IF;

EXECUTE IMMEDIATE WITH RESULT SET ON Command;

END;

如果按如下方式调用该过程:

CALL DynamicResult(

'table_id,table_name',

'SYSTAB',

'table_id <= 10');

它将生成以下结果:

table_id

table_name

1

ISYSTAB

2

ISYSTABCOL

3

ISYSIDX

...

...

上述 CALL 将正确返回结果集,即使过程利用 EXECUTE IMMEDIATE 也是如此。一些服务器 API(例如 ODBC)将请求与 PREPARE-DESCRIBE-EXECUTE-OR-OPEN 结合使用,从而根据其是否返回结果集来决定是执行语句还是打开语句。如果打开语句,API

或应用程序可随即发出 DESCRIBE CURSOR 来确定实际结果集的外观,而不是依赖于创建过程时 SYSPROCPARM 系统视图的内容。DBISQL 和 DBISQLC 均使用此技术。在上述情况下,对以上过程的 CALL 将会正确执行。但是,依赖于语句的

DESCRIBE 结果的应用程序接口将无法处理任意语句。

在原子复合语句中,不能使用导致 COMMIT(提交)的 EXECUTE IMMEDIATE 语句,因为在该上下文中不允许 COMMIT。

oracle 触发器 execute immediate,过程、触发器、用户定义函数和批处理中使用的 EXECUTE IMMEDIATE...相关推荐

  1. 使用脚本编写 Vim 编辑器,第 2 部分: 用户定义函数

    用户定义函数 Haskell 或 Scheme 程序员会告诉您,函数对于任何严肃的编程语言来说都是最重要的特性.对于 C 或 Perl 程序员,他们也会告诉您完全相同的观点. 函数为严肃的程序员提供了 ...

  2. SQL Prompt数据库教程:标量用户定义函数误用作常量

    SQL Prompt是一款实用的SQL语法提示工具.SQL Prompt根据数据库的对象名称.语法和代码片段自动进行检索,为用户提供合适的代码选择.自动脚本设置使代码简单易读–当开发者不大熟悉脚本时尤 ...

  3. 数据库原理与应用(SQL Server)笔记 第十章 用户定义函数

    目录 前言 一.用户定义函数的定义 二.用户定义函数的分类 三.标量函数和内联表值函数 (一)标量函数的定义 (二)标量函数的调用 1.SELECT语句调用 2.EXEC语句调用 (三)内联表值函数的 ...

  4. SQL service基础(九)用户定义数据类型和用户定义函数的概念、创建及使用方法

    实验目标: 1.学习和掌握用户定义数据类型的概念.创建及使用方法. 2.学习和掌握用户定义函数的概念.创建及使用方法. 创建一个数据库,执行shiyan15.sql脚本 一.创建和使用用户定义的函数( ...

  5. db2 控制台执行创建函数语句_DB2中创建和使用SQL用户定义函数

    本文将为您详细介绍DB2数据库中创建用户自定义行数,用以扩展扩展内置的 DB2 函数的方法,供您参考,希望对您有所帮助. 可以创建用户定义函数来扩展内置的 DB2 函数.例如,创建计算复杂的算术表达式 ...

  6. keil运行c语言输入函数,keil 编译器V6 定义函数在ram中运行-和在指定地址定义常量,keil编译器...

    keil 编译器V6 定义函数在ram中运行-和在指定地址定义常量,keil编译器 之前一直是用v5编译,编译速度慢,换成V6编译速度差不多快50% ,而且arm后期只维护v5编译器不在更新v5编译器 ...

  7. 用 Wasm 为数据库增加用户定义函数

    作者: arcosx 百度高级研发工程师,负责机器学习平台研发 前言 UDF (User-defined function) 意为用户提供或定义的函数.在数据库领域,UDF 代表一种机制:通过添加一个 ...

  8. python自定义函数找最大值_python – 查找用户定义函数的局部最大值和最小值

    我想要的是 我想找到一个静止点列表,它们的值和位置,以及它们是最小值还是最大值. 我的功能如下: import numpy as np def func(x,y): return (np.cos(x* ...

  9. JavaScript | 用户定义函数的一些示例

    1) Design a function, print message and assign the function to a variable and print it like a functi ...

最新文章

  1. 生成对抗网络(GAN)
  2. opengl es 2.0环境
  3. Python3 解释执行字符串类型的代码
  4. Linux之物理页面的分配
  5. 8个球放入3个盒子方式_球放进盒子问题(8种, 可变形)
  6. python智能机器人设计与实现_从AI模型到智能机器人:基于Python与TensorFlow
  7. 结合上下文和篇章特征的多标签情绪分类
  8. 如何在Mac上恢复已删除或丢失的分区
  9. linux mysql 配置root_Linux配置(mysql安装篇)
  10. NYOJ题目289/456/49-01背包问题汇总
  11. 第九届大唐杯省赛知识梳理-5G协议与信令(20%)
  12. 设置谷歌浏览器深色黑色背景
  13. STM32F401 / STM32F411 WeAct Studio 资料以及翻版说明
  14. Android实现校园新闻APP,基于android平台的校园新闻app的开发 大学毕业论文.doc
  15. 基于HFSS的圆形左旋圆极化贴片天线仿真分析
  16. 基于C语言扫雷游戏的设计与实现
  17. TFN TT70网络综合分析仪性能如何
  18. 微信小程序开发监听器教程
  19. 离职了半年了,大家觉得我为啥离职呢?
  20. 出乎意料,5G最大赢家是苹果而不是华为

热门文章

  1. 华为视频编辑服务(Video Editor Kit),助力开发者高效构建应用视频编辑能力
  2. 蓝桥杯C/C++VIP试题每日一练之回形取数
  3. MySQL分组统计及占比分析的方法实现
  4. 硬件服务器优化,hbase 服务器优化之硬件优化(用好操作系统)
  5. NeuroImage: 7-13岁儿童执行功能发育的脑网络研究
  6. JAVA_Lesson14(传智播客笔记之多线程)
  7. matlab怎么自动保存plot生成的图像,fig格式或者png格式
  8. SSP和SCP的介绍
  9. 在OpenCV里实现负片函数imcomplement
  10. 迅睿CMS 网站表单管理