浅析PowerBuilder下动态SQL语句
作者:张继荣 王举国 谭琦 谢元呈
PowerBuilder是目前最流行的数据库开发工具之一。PowerBuilder提供了在程序代码中加入嵌入式SQL语句的功能来支持对数据库的访问。但这种嵌入式SQL语句只能支持一些固定的标准的SQL语句,即在进行程序代码编译处理时这些SQL语句必须是确定的,例如:对哪张表哪几个字段进行操作在程序代码中是固定写明的,另外这种方式也不能执行像Creat Table,Creat Database等这些数据库定义的语句(DDL)。
因此这种嵌入式SQL语句在实际应用中有一定的局限性。为克服这种方式的局限性,可以使用PowerBuilder提供的动态SQL语句,这种对数据库访问的方式可以完成嵌入式SQL语句无法实现的功能。如建库、建表这一类的数据库定义语句(DDL);其次,由于动态SQL语句允许在执行时才确定到底要执行怎样的SQL语句,因此使用动态SQL语句可以使程序实现参数化设计,具有很大的灵活性和通用性。
一、动态SQL语句的应用分析 PowerBuilder提供了四种格式的动态SQL语句,每种格式都有自己不同的特点和作用。下面我们对各种格式的具体使用方法分别加以说明。
(一)第一种格式
当执行没有输入参数并且没有返回结果集的SQL语句时可以使用这种格式,这种格式使用比较简单,其实现的操作也比较少。
1语法
EXECUTE IMMEDIATE SQLStatement{USING TransactionObject};
其中SQLStatement是要执行的SQL语句,可以直接用引号将要执行的SQL引起来用,或者用字符串变量的形式提供SQL语句。通过使用字符串变量可以在具体执行的时候才指定要执行什么样的SQL语句。TransactionObject是用户所使用的事务对象,缺省为SQLCA。
2应用实例
①建立一张数据库表(base),SQL语句的表述用引号引起来直接使用。
EXECUTE IMMEDIATE‘CREATE TABLE base(code char(6),name char(30))’USING SQLCA;
②执行对数据库记录的操作,在表base中插入一条记录,SQL语句通过字符串变量传递执行语句。
STRING lsSQL
LsSQL=”INSERT INTO TABLE base VALUES(’320201’,’市中区支行’)”
EXECUTE IMMEDIATE:lsSQL;
(二)第二种格式
当执行带输入参数但没有返回结果集时的SQL语句可以采用第二种格式。该格式不仅可以动态地指定要执行的SQL语句,同时还可以动态地确定SQL语句所需要的参数值。
1语法
PREPARE DynamicStagingArea FROM SQLStatement{USING TransactionObject};
EXECUTE DynamicstagingArea{USING Parameterlist};
其中:DynamicstagingArea是PowerBuilder提供的一种数据类型。PowerBuilder本身提供了一个名字为SQLSA的DynamicstagingArea类型的全局变量,用于保存要执行的动态SQL语句信息。
2应用实例
删除base表中的满足一定条件的记录。
STRING lsCode
lsCode=”320101”
PREPARE SQLSA FROM“DELETE base WHERE code=?”;
EXECUTE SQLSA USING:lsCode;
(三)第三种格式
当执行有输入参数并且返回结果集的格式在编译时可以确定的SQL语句时可以使用第三种格式。这种格式语法比较复杂,但要比前面两种功能强,可以返回结果集。在返回结果时由于不知道满足过滤条件的记录到底有多少条,因此第三种格式通常采用游标的形式。
1语法
DECLARE cursor DYNAMIC CURSOR FOR DynamicStagingArea;
PREPARE DynamicStagingArea FROM SQLStatement{USING TransactionObject};
OPEN DYNAMIC cursor {USING Parameterlist};
FETCH cursor INTO VariableList;
CLOSE cursor;
其中cursor是用户所定义的游标的名字。
2应用实例
将表base中的code字段中间两位为”01”的所有记录读取出来并分别进行相应处理。
STRING lsSQL,lsCode,lsName,lsFilter
LsFilter=”01”
LsSQL=”SELECT code,name FROM base WHERE substring(code,3,2)=?”
DECLARE cursor_base DYNAMIC CURSOR FOR SQLSA;
PREPARE SQLSA FROM:lsSQL;
OPEN DYNAMIC cursor_base USING:lsFilter;
FETCH cursor_base INTO:lsCode,:lsName;
DO WHILE SQLCA.SQLCODE=0
. ∥对满足条件的记录根据要求分别进行处理
. FETCH cursor_base INTO:lsCode,:lsName;
LOOP
CLOSE cursor_base;
(四)第四种格式
当执行有输入参数并且返回结果集的格式在编译时无法确定的SQL语句时可以使用第四种格式。有时候我们执行一些SQL语句时,不仅带有参数而且返回的结果集中有多少个字段,每个字段是什么类型的数据都不确定,这时只能使用第四种格式来实现。
1语法
PREPARE DynamicStagingArea FROM SQLStatement{USING TransactionObject};
DESCRIB DynamicStagingArea INTO DynamicDescriptionObject;
DECLARE cursor DYNAMIC CURSOR FOR DynamicDescriptionObject;
OPEN DYNAMIC cursor USING DESCRIPTOR DynamicDescriptionObject;
FETCH cursor USING DESCRIPTOR DynamicDescriptionObject;
CLOSE cursor;
其中:DynamicDescriptionObject是PowerBuilder提供的一个数据类型,在PowerBuilder中提供了一个DynamicDescriptionObject类型的全局数据类型SQLDA,用来存放动态SQL语句的输入输出参数。
2应用实例
将一个表中满足过滤条件的记录的所有字段取出来分别进行处理,表名在程序运行中由字符串变量传递,字段信息是不确定的。这里我们假设通过字符串变量中传递的表名是base。
STRING lsString,lsSQL,lsTable,lsColumn
INT liInt
DATETIME liTime
LsSQL=”SELECT*FROM base WHERE code like?”
PREPARE SQLSA FROM lsSQL;
DESCRIB SQLSA INTO SQLDA;∥SQLDA中含有输入参数的描述
DECLARE cursor_base DYNAMIC CURSOR FOR SQLSA;
SetDynamicparm(SQLDA,1,”32%”)∥传递参数值
OPEN DYNAMIC cursor_base USING DESCRIPTOR SQLDA;
FETCH cursor_base USING DESCRIPTOR SQLDA;
DO WHILE SALCA.SQLCODE=0
FOR liInt=1 TO SQLDA.NumOutPuts
CHOOSE CASE SQLDA.OutParmType[liInt]
CASE Typestring!
lsString=GetDynamicString(SQLDA,liInt)
∥处理该字符型的字段
CASE TypeDateTime
LsDateTime=GetDynamicDateTime(SQLDA,liInt)
∥处理该日期型的字段
... ∥处理其他类型的字段
... END CHOOSE
NEXT
∥将一条记录的所有字段取完后作相应的处理
FETCH cursor_base USING DESCRIPTOR SQLDA;
LOOP
CLOSE cursor_base;
二、结束语
从上面的说明和举例中可以看出动态SQL的特点是功能强,使用灵活,完全可以在程序代码中动态地生成具体要执行的SQL语句,是嵌入式SQL无法比拟的。当然动态SQL语句在运行速度上可能要比嵌入式SQL语句略慢一点,但随着计算机处理速度的大幅度提高,现在来说这一点已不成什么问题。
因此,使用动态SQL语句仍是一种非常可取的处理方法。根据我们在实际编程中的体会,正确使用动态SQL语句可使程序代码简练、灵活、通用,不仅降低了初次编程的工作量,而且也降低以后对代码的维护量,能够取得事半功倍的效果。
【PB】动态SQL语句
所谓动态SQL语句是指部分或者整个SQL语句在运行时才能确定,这样的SQL语句可以用来设计能和用户进行更好交互的界面。因为参数的确定留给用户总比编程时由开发人员规定死要好得多。另外, PowerBuilder不支持有些SQL语句的嵌入执行,例如Create Table,Drop Table等,需要将这些SQL语句交给DBMS执行,而动态SQL语句都是将SQL语句交给DBMS执行的。这些都是要掌握动态SQL语句的原因。
动态SQL语句有四种类型:
l 既无输入参数,也无结果集;
l 有输入参数,但没有结果集;
l 编译时已经知道参数和结果集的列;
l 开发程序时尚不知道参数和结果集。
10.2.1 类型一
这种类型的动态SQL语句经常用来执行DDL或者数据库专用的其他SQL语句。语法格式是:
EXECUTE IMMEDIATE SQLStatement {USING TransactionObject} ;
其中SQLStatement是个字符串,其内容是有效的SQL语句;TransactionObject是事务对象名,大括号表示该子句可以省略,省略时使用SQLCA。下面是个创建删除数据表的例子:
string MySQLMySQL = "drop table employee"
EXECUTE IMMEDIATE :MySQL USING SQLCA;
运行之前已知参数个数并且没有返回值时使用这种类型的动态SQL语句。这种类型的动态SQL语句也能够处理需要在运行时定义参数的数据操作语句。其语法格式为:
PREPARE DynamicStagingArea FROM SQLStatement
EXECUTE DynamicStagingAreaUSING {ParameterList} ;
PREPARE SQLSA FROM "DELETE FROM employee WHERE emp_id=?" ;
EXECUTE SQLSA USING :Emp_id_var ;
"Insert inTo employee (emp_id,manager_id) value (?,?)"
execute SQLSA using :ls_EmpId,:sle_manager.text;
这种类型的动态SQL语句的使用频率可能是仅次于第一种类型,它常用来处理参数个数和结果集在编译时已知的情况,又分为游标和存储过程两种情况。使用游标形式的语法与程序中出现的次序为:
DECLARE Cursor DYNAMIC CURSOR FOR DynamicStagingArea ;
PREPARE DynamicStagingArea FROM SQLStatement{USING TransactionObject} ;
OPEN DYNAMIC Cursor{USING ParameterList} ;
FETCH Cursor |INTO HostVariableList} ;
使用存储过程的第三类动态SQL语句的格式和次序与上面的语法形式类似,只是使用EXECUTE语句来代替上面的OPEN语句,其语法格式为:
DECLARE Procedure DYNAMIC PROCEDUREFOR DynamicStagingArea ;
PREPARE DynamicStagingArea FROM SQLStatement
EXECUTE DYNAMIC Procedure{USING ParameterList} ;
FETCH ProcedureINTO HostVariableList} ;
DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA;
String SQLstatement,Emp_state_var = "北京"
SQLstatament = "SELECT emp_id FROM employee WHERE emp_state = ?"
PREPARE SQLSA FROM :SQLstatement;
OPEN DYNAMIC my_cursor using :Emp_state_var;
FETCH my_cursor INTO :Emp_id_var;
该示例中省略了必要的SQL语句执行状态检查工作,在实际编写程序时,除DECLARE语句外,执行了其他SQL语句后,都应该检查事务对象的SQLCode属性,以判断SQL语句的执行是否成功。
使用这种类型的动态SQL语句可以创建比较通用的向列表框或者下拉列表框中添加数据的脚本。
//函数名称wf_AddItem(dropdownlistbox fo_obj,string fs_SQL)
//参数:fo_obj为下拉列表框,fs_SQL为SQL语句
//功能:使用参数指定的SQL语句向指定的下拉列表框中添加数据
Declare item_cur Dynamic Cursor For SQLSA; //定义动态光标
Prepare SQLSA From :fs_SQL Using SQLCA;
Open Dynamic item_cur; //打开动态光标
Fetch item_cur InTo :ls_item; //取数据
fo_obj.SetRedraw(False) //禁止下拉列表框刷新
fo_obj.AddItem(ls_item) //向下拉列表框中添加项目
fo_obj.SetRedraw(True) //刷新下拉列表框
10.2.4 类型四
DECLARE Cursor | ProcedureDYNAMIC CURSOR |
PROCEDUREFOR DynamicStagingArea;
PREPARE DynamicStagingArea FROM SQLStatement
DESCRIBE DynamicStagingArea INTO DynamicDescriptionArea;
OPEN DYNAMIC CursorUSING DESCRIPTOR DynamicDescriptionArea};
EXECUTE DYNAMIC ProcedureUSING DESCRIPTOR DynamicDescriptionArea;
FETCH Cursor | ProcedureUSING DESCRIPTOR DynamicDescriptionArea;
函 数 名 |
适用的参数类型 |
GetDynamicNumber() |
TypeInteger! TypeDecimal! TypeDouble! TypeLong!TypeReal! TypeBoolean! TypeUnsignedInteger! TypeUnsignedLong! |
GetDynamicString() |
TypeString! |
GetDynamicDate() |
TypeDate! |
GetDynamicTime() |
TypeTime! |
GetDynamicDateTime() |
TypeDateTime! |
通过使用该对象变量的函数SetDynamicParm()设置具体的输入参数值。通过使用表10-6中的对象函数得到输出参数(实际上就是SQL语句的返回数据)的值,每个函数都针对特定的数据类型。
输出参数的类型后再用表10-6中的对象函数得到其值。下面是第四类动态SQL语句的一个应用示例,其中省略了实际编程中必须具备的检查事务对象SQLCode属性的过程(即检查SQL语句执行是否成功):
ls_SqlStatement = "SELECT emp_id FROM employee"
Prepare SQLSA From : ls_SqlStatement ;
Declare my_cursor Dynamic Cursor For SQLSA ;
Open Dynamic my_cursor Using DescripTor SQLDA ;
Fetch my_cursor Using DescripTor SQLDA ;
MesasgeBox("提示", "没有找到指定的数据! ")
//当FETCH语句执行成功时,动态描述区SQLDA中包含了结果集的
// SQLDA.NumOutputs中包含了输出参数的个数。
// SQLDA.OutParmType数组中包含了各参数的数据类型,
//例如TypeInteger!, 或 TypeString!等
//使用CHOOSE CASE语句针对不同的输出参数类型调用不同的对象函数
Choose Case SQLDA.OutParmType[1]
Stringvar = GetDynamicString(SQLDA, 1)
Intvar = GetDynamicNumber(SQLDA, 1)
Loop While li_count <> SQLDA.NumOutPuts
浅析PowerBuilder下动态SQL语句相关推荐
- Oracle基础 动态SQL语句
一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...
- 动态SQL语句--mybatis
转自:http://www.blogjava.net/Steven-bot/articles/363460.html 动态SQL语句--mybatis 动态SQL语句 有些时候,sql ...
- Mybatis Plus 是如何实现动态 SQL 语句的?原理你懂吗?
作者 | 稻草江南 来源 | https://juejin.cn/post/6883081187103866894 Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,那么它是怎么 ...
- MyBatis——动态SQL语句——if标签和where标签复合使用
功能需求 根据性别和名字查询用户 官方文档 MyBatis--动态 SQL SQL语句 SELECT id, username, birthday, sex, address FROM `user` ...
- oracle不使用游标,oracle – 为什么我们不能在动态SQL语句中使用强引用游标?
这是一个带有强类型引用游标的过程: SQL> create or replace procedure p1 is 2 type dept_rc is ref cursor return dept ...
- oracle 带有变量的语句_Oracle 动态SQL语句(2)之含变量的WHERE语句与日期变量
在 Oracle 动态SQL语句(1)中提到基本动态SQL语句书写,但在写动态SQL语句时特别要注意日期型变量和WHERE语句的编写. 如下代码: 1.注意在执行动态SQL语句时,execute im ...
- 存储过程中执行动态Sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...
- Mybatis 动态Sql语句《常用》
MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉 ...
- 【转】mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句
转自:除非申明,文章均为一号门原创,转载请注明本文地址,谢谢! 转载地址:http://blog.csdn.net/kutejava/article/details/9164353#t5 1. if ...
最新文章
- java与servlet JSP_java面试精品全集[jsp与servlet部分]
- Python字符串处理函数
- select for update
- 电商必备:如何选择第三方快递?
- 计划策略-52-没有最终装配和没有MTO的计划
- vim normal 模式下L键
- 王道计算机网络 数据链路层整理 超详细版
- dns服务器的配置与管理
- python列表有哪些操作_python列表的基本操作有哪些
- android 梅花布局,Android相对布局实现各种梅花效果
- 图论:有源汇有上下界最小流
- sql语句如何拼接Java变量
- HTML实现简易音乐网站
- 微软的补丁服务器,Microsoft 安全公告 MS17-010 - 严重
- 【LOJ】 #2520. 「FJOI2018」所罗门王的宝藏
- git 如何下载单个文件夹或者单个文件
- iOS 横线贯穿文字
- Kaka集群生产者消费者使用实例(二)
- 如何用c语言程序预测身高,测身高的C语言程序.doc
- CSAPP : Arch Lab 解题报告
热门文章
- mysql 枚举字段,MySQL字段中的枚举是什么意思 | 学步园
- 自定义悬浮球,提供一些快捷操作。比如一键静音,一键锁频,一键截屏,一键回桌面,手电筒等
- PC_ 计算机系统概述+冯诺依曼机+各种字长
- 蚪侠-远程泛目录V21(镜像版)-免授权
- linux通过手机热点上网耗流量,电脑通过手机热点上网,是不是比手机用流量更费一些?...
- 贝塞尔曲线(Bezier)之爱心点赞曲线动画效果
- pandas读取大csv报错:TypeError: ufunc ‘isnan‘ not supported for the input types, and the inputs could not
- 4.3 51单片机-串口通信
- Linux实现ISCSI共享设备
- Kubernetes Kubelete 报错 ctr: failed to create shim task: OCI runtime create failed