PB从入坑到放弃(六)动态SQL应用

打印 上一主题 下一主题

主题 874|帖子 874|积分 2622

写在前面

动态 SQL 语句是部分或者整个 SQL 语句在运行时才能确定,可以更好的与用户进行交互,大大提高了SQL的灵活性
一、执行SQL语句

1.1 执行无入参SQL

① 语法
  1. EXECUTE IMMEDIATE SQLStatement {USING TransactionObject} ;
复制代码
② 说明

  • SQLStatement  --> 有效SQL语句字符串
  • TransactionObject   -->事务对象名  省略时使用 SQLCA
③ 举个栗子
删除员工信息表emp
  1. string sql = "drop table emp"
  2. EXECUTE IMMEDIATE :sql USING SQLCA;
复制代码
1.2 执行带参数SQL

① 语法
  1. PREPARE DynamicStagingArea FROM SQLStatement
  2. {USING TransactionObject} ;
  3. EXECUTE DynamicStagingAreaUSING {ParameterList} ;
复制代码
②说明

  • DynamicStagingArea  -->默认全局变量是 SQLSA
  • SQLStatement   -->有效的SQL语句,其中? 代表需要传入的参数。执行时问号被 EXECUTE 语句中的 USING 子句所代表的值
    取代
  • TransactionObject-->事务对象名,大括号表示该子句可以省略,省略时使用 SQLCA
  • ParameterList -->参数列表,可以是变量、常量或者控件的属性,各参数对应于 SQLStatement中的问号
③ 举个栗子
Ⅰ 删除员工编号56的员工信息
  1. Int li_empno = 56
  2. PREPARE SQLSA FROM "DELETE FROM emp WHERE empno=?" ;
  3. EXECUTE SQLSA USING :li_empno ;
复制代码
Ⅱ 新增一个员工信息
  1. Prepare SQLSA from
  2. "insert into emp  (empno, ename, job, mgr, hiredate, sal, comm, deptno) values  (?, ?, ?, ?, ?, ?, ?, ?)"
  3. execute SQLSA using :ls_empno, :ls_ename, :ls_job, :ls_mgr, :ld_hiredate, :ld_sal, :ls_comm, :ls_deptno;
复制代码
二 、使用游标

数据库中的游标可以看作是一个指针,它指向查询语句返回的结果集中的当前行。通过游标,我们可以逐行处理结果集
2.1  语法

① do while 语法
  1. //定义游标
  2. string test
  3. //声明游标
  4. declare test cursor for select 字段名 from 表名 where 条件 using sqlca;
  5. //打开游标
  6. open test;
  7. //获取数据
  8. fetch test into:字段名变量;
  9. do while sqlca.sqlcode = 0
  10. //在这里写你的业务
  11. //再次获取数据
  12. fetch test into:字段名变量;
  13. loop
  14. //关闭游标
  15. close test;
复制代码
②  for 语法
  1. long ll_count = 10
  2. //定义游标
  3. string test
  4. //声明游标
  5. declare test cursor for select 字段名 from 表名 where 表达式 using sqlca;
  6. //打开游标
  7. open test;
  8. for i=1 to ll_count
  9. //获取数据
  10. fetch test into :变量名;
  11. //在这里写你的业务
  12. next
  13. //关闭游标
  14. close test;
复制代码
2.2 举个栗子

上面具体说了游标的两种实现语法,接下来我们就分别用两种语法实现向下拉框中添加数据的功能
① 使用do while 语法向下拉框中添加员工信息
  1. string ls_empno,ls_ename
  2. ddlb_1.Reset ()              //重置下拉列表
  3. DECLARE cur_empinfo CURSOR FOR
  4. select empno,ename from emp;
  5.    
  6. Open cur_empinfo;      // 打开游标
  7. If SQLCA.SqlCode = -1 Then      //判断打开游标是否失败,失败则弹出提示信息
  8.   messagebox ('提示信息'+SQLCA.SqlErrText)
  9.   Return -1
  10. End If
  11.   
  12. Fetch cur_empinfo Into :ls_empno,:ls_ename;
  13. ddlb_1.SetRedraw(False)   //禁止下拉列表刷新
  14. Do While SQLCA.SqlCode = 0
  15.   ddlb_1.AddItem (ls_empno+'-'+ls_ename)  //向下拉列表添加数据
  16.   Fetch cur_empinfo Into :ls_empno,:ls_ename;
  17. Loop
  18. ddlb_1.SetRedraw(True)  //刷新下拉列表
  19. Close cur_empinfo;  //关闭游标
复制代码
②  使用for 语法向下拉框中添加员工信息
  1. long ll_count = 10
  2. string ls_empno,ls_ename
  3. //定义游标
  4. string cur_empinfo
  5. //声明游标
  6. declare cur_empinfo cursor for select empno,ename from emp where deptno = '20' using sqlca;
  7. //打开游标
  8. open cur_empinfo;
  9. for i=1 to ll_count
  10. //获取数据
  11. fetch test into :ls_empno,:ls_ename;
  12.     //在这里写你的业务
  13.     ddlb_1.AddItem (ls_empno+'-'+ls_ename)  //向下拉列表添加数据
  14. next
  15. //关闭游标
  16. close cur_empinfo;
复制代码
注: 使用游标过程中,打开了游标,业务处理完之后一定要关闭游标
三 、调用存储过程

存储过程是一组预编译的SQL代码块,它将一些复杂操作封装起来,并存储在数据库中。
由于存储过程在数据库中进行了预编译,并且能被多个客户端重复调用,可以减少网络开销,提高执行效率
3.1 调用格式
  1. // 定义过程调用
  2. // prc_Test 表示数据库中存储过程名称
  3. // ls_a,ls_b 表示存储过程中的in类型入参
  4. Declare my_proce Procedure For prc_Test(:ls_a,:ls_b);  
  5. // 执行过程,这里是不需要其他参数的
  6. Execute my_proce ;
  7. // 调用过程出现错误处理
  8. If SQLCA.SQLCode <> 0 Then
  9. End If
  10. // 获取出参值,也就是OUT的变量,如果没有out类型的变量,这句也就不需要了
  11. Fetch my_proce Into :ls_ReturnName;
  12. // 获取数据出现错误处理
  13. If SQLCA.SQLCode <> 0 Then
  14. End If
  15. // 关闭调用
  16. Close my_proce ;
复制代码
3.2 举个栗子

① PB调用无入参存储过程
Ⅰ 创建存储过程
  1. Create Or Replace Procedure prc_getEmplname(v_name Out Varchar2) As
  2. --存储过程,有一个out类型参数,无入参
  3. Begin
  4.     v_name := 'Jone';
  5. End;
复制代码
Ⅱ 调用存储过程
  1. Declare my_proce Procedure For p_get_name;  
  2. //或者
  3. Declare my_proce Procedure For p_get_name();
复制代码
② PB调用有入参存储过程
Ⅰ 创建存储过程
我们来创建一个存储过程,根据部门编号和员工姓名给该员工涨1000块钱工资
  1. CREATE OR REPLACE Procedure prc_incr_sal(pra_deptno in Varchar2,
  2.                                        pra_ename  in varchar2,
  3.                                        pra_code   out NUMBER,    --执行代码
  4.                                        pra_errmsg out VARCHAR2) As
  5. Begin
  6.    pra_code :=1;
  7.    pra_errmsg :='';
  8.    begin
  9.    update emp set sal=sal+1000 where deptno = pra_deptno and ename =pra_ename;
  10.     EXCEPTION
  11.       WHEN OTHERS THEN
  12.          pra_code := -1;
  13.          pra_errmsg := '更新员工薪水失败!'||SQLERRM;
  14.    END;
  15. End prc_incr_sal;
复制代码
Ⅱ 调用存储过程
  1. string ls_deptno
  2. string ls_ename
  3. int li_AppCode
  4. string ls_err
  5. ls_deptno = "20"
  6. ls_ename = "XIEZHR"
  7. DECLARE my_prc PROCEDURE FOR PRC_INCR_SAL
  8.         (:ls_deptno, //员工编号
  9.      :ls_ename  //员工姓名
  10.         );
  11. EXECUTE my_prc;
  12. // 执行存储过程报错处理
  13. IF SQLCA.SQLCode < 0 THEN
  14.         ls_err = SQLCA.SQLErrText
  15.         GOTO prcErr
  16. END if
  17. //获取存储过程出参数据
  18. FETCH my_prc Into :li_AppCode, :ls_err ;
  19. //获取出参数据失败处理
  20. IF SQLCA.SQLCode < 0 THEN GOTO prcErr
  21. IF li_AppCode < 0 THEN GOTO prcErr
  22. //关闭存储过程
  23. CLOSE my_prc;
  24. return 0
  25. prcErr:
  26.     rollback;
  27.     messagebox('错误信息',)
复制代码
四、小结

通过前面的三小节内容,相信你已经学会了在PB中怎么执行动态SQL语句?PB怎么调用数据库中存储过程?
PB怎么通过游标对SQL语句查询出的包含多条结果集的处理。这几种场景在PB中都是经常使用的。
以上就是本期的全部内容,希望对你有所帮助 (●'◡'●)
我们下期再见~  ヾ(•ω•`)o

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

前进之路

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表