写在前面
动态 SQL 语句是部分或者整个 SQL 语句在运行时才能确定,可以更好的与用户进行交互,大大提高了SQL的灵活性
一、执行SQL语句
1.1 执行无入参SQL
① 语法- EXECUTE IMMEDIATE SQLStatement {USING TransactionObject} ;
复制代码 ② 说明
- SQLStatement --> 有效SQL语句字符串
- TransactionObject -->事务对象名 省略时使用 SQLCA
③ 举个栗子
删除员工信息表emp
- string sql = "drop table emp"
- EXECUTE IMMEDIATE :sql USING SQLCA;
复制代码 1.2 执行带参数SQL
① 语法- PREPARE DynamicStagingArea FROM SQLStatement
- {USING TransactionObject} ;
- EXECUTE DynamicStagingAreaUSING {ParameterList} ;
复制代码 ②说明
- DynamicStagingArea -->默认全局变量是 SQLSA
- SQLStatement -->有效的SQL语句,其中? 代表需要传入的参数。执行时问号被 EXECUTE 语句中的 USING 子句所代表的值
取代
- TransactionObject-->事务对象名,大括号表示该子句可以省略,省略时使用 SQLCA
- ParameterList -->参数列表,可以是变量、常量或者控件的属性,各参数对应于 SQLStatement中的问号
③ 举个栗子
Ⅰ 删除员工编号56的员工信息- Int li_empno = 56
- PREPARE SQLSA FROM "DELETE FROM emp WHERE empno=?" ;
- EXECUTE SQLSA USING :li_empno ;
复制代码 Ⅱ 新增一个员工信息- Prepare SQLSA from
- "insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (?, ?, ?, ?, ?, ?, ?, ?)"
- execute SQLSA using :ls_empno, :ls_ename, :ls_job, :ls_mgr, :ld_hiredate, :ld_sal, :ls_comm, :ls_deptno;
复制代码 二 、使用游标
数据库中的游标可以看作是一个指针,它指向查询语句返回的结果集中的当前行。通过游标,我们可以逐行处理结果集
2.1 语法
① do while 语法- //定义游标
- string test
- //声明游标
- declare test cursor for select 字段名 from 表名 where 条件 using sqlca;
- //打开游标
- open test;
- //获取数据
- fetch test into:字段名变量;
- do while sqlca.sqlcode = 0
- //在这里写你的业务
- //再次获取数据
- fetch test into:字段名变量;
- loop
- //关闭游标
- close test;
复制代码 ② for 语法- long ll_count = 10
- //定义游标
- string test
- //声明游标
- declare test cursor for select 字段名 from 表名 where 表达式 using sqlca;
- //打开游标
- open test;
- for i=1 to ll_count
- //获取数据
- fetch test into :变量名;
- //在这里写你的业务
- next
- //关闭游标
- close test;
复制代码 2.2 举个栗子
上面具体说了游标的两种实现语法,接下来我们就分别用两种语法实现向下拉框中添加数据的功能
① 使用do while 语法向下拉框中添加员工信息- string ls_empno,ls_ename
- ddlb_1.Reset () //重置下拉列表
- DECLARE cur_empinfo CURSOR FOR
- select empno,ename from emp;
-
- Open cur_empinfo; // 打开游标
- If SQLCA.SqlCode = -1 Then //判断打开游标是否失败,失败则弹出提示信息
- messagebox ('提示信息'+SQLCA.SqlErrText)
- Return -1
- End If
-
- Fetch cur_empinfo Into :ls_empno,:ls_ename;
- ddlb_1.SetRedraw(False) //禁止下拉列表刷新
- Do While SQLCA.SqlCode = 0
- ddlb_1.AddItem (ls_empno+'-'+ls_ename) //向下拉列表添加数据
- Fetch cur_empinfo Into :ls_empno,:ls_ename;
- Loop
- ddlb_1.SetRedraw(True) //刷新下拉列表
- Close cur_empinfo; //关闭游标
复制代码 ② 使用for 语法向下拉框中添加员工信息- long ll_count = 10
- string ls_empno,ls_ename
- //定义游标
- string cur_empinfo
- //声明游标
- declare cur_empinfo cursor for select empno,ename from emp where deptno = '20' using sqlca;
- //打开游标
- open cur_empinfo;
- for i=1 to ll_count
- //获取数据
- fetch test into :ls_empno,:ls_ename;
- //在这里写你的业务
- ddlb_1.AddItem (ls_empno+'-'+ls_ename) //向下拉列表添加数据
- next
- //关闭游标
- close cur_empinfo;
复制代码 注: 使用游标过程中,打开了游标,业务处理完之后一定要关闭游标
三 、调用存储过程
存储过程是一组预编译的SQL代码块,它将一些复杂操作封装起来,并存储在数据库中。
由于存储过程在数据库中进行了预编译,并且能被多个客户端重复调用,可以减少网络开销,提高执行效率
3.1 调用格式
- // 定义过程调用
- // prc_Test 表示数据库中存储过程名称
- // ls_a,ls_b 表示存储过程中的in类型入参
- Declare my_proce Procedure For prc_Test(:ls_a,:ls_b);
- // 执行过程,这里是不需要其他参数的
- Execute my_proce ;
- // 调用过程出现错误处理
- If SQLCA.SQLCode <> 0 Then
- End If
- // 获取出参值,也就是OUT的变量,如果没有out类型的变量,这句也就不需要了
- Fetch my_proce Into :ls_ReturnName;
- // 获取数据出现错误处理
- If SQLCA.SQLCode <> 0 Then
- End If
- // 关闭调用
- Close my_proce ;
复制代码 3.2 举个栗子
① PB调用无入参存储过程
Ⅰ 创建存储过程- Create Or Replace Procedure prc_getEmplname(v_name Out Varchar2) As
- --存储过程,有一个out类型参数,无入参
- Begin
- v_name := 'Jone';
- End;
复制代码 Ⅱ 调用存储过程- Declare my_proce Procedure For p_get_name;
- //或者
- Declare my_proce Procedure For p_get_name();
复制代码 ② PB调用有入参存储过程
Ⅰ 创建存储过程
我们来创建一个存储过程,根据部门编号和员工姓名给该员工涨1000块钱工资
- CREATE OR REPLACE Procedure prc_incr_sal(pra_deptno in Varchar2,
- pra_ename in varchar2,
- pra_code out NUMBER, --执行代码
- pra_errmsg out VARCHAR2) As
- Begin
- pra_code :=1;
- pra_errmsg :='';
- begin
- update emp set sal=sal+1000 where deptno = pra_deptno and ename =pra_ename;
- EXCEPTION
- WHEN OTHERS THEN
- pra_code := -1;
- pra_errmsg := '更新员工薪水失败!'||SQLERRM;
- END;
- End prc_incr_sal;
复制代码 Ⅱ 调用存储过程- string ls_deptno
- string ls_ename
- int li_AppCode
- string ls_err
- ls_deptno = "20"
- ls_ename = "XIEZHR"
- DECLARE my_prc PROCEDURE FOR PRC_INCR_SAL
- (:ls_deptno, //员工编号
- :ls_ename //员工姓名
- );
- EXECUTE my_prc;
- // 执行存储过程报错处理
- IF SQLCA.SQLCode < 0 THEN
- ls_err = SQLCA.SQLErrText
- GOTO prcErr
- END if
- //获取存储过程出参数据
- FETCH my_prc Into :li_AppCode, :ls_err ;
- //获取出参数据失败处理
- IF SQLCA.SQLCode < 0 THEN GOTO prcErr
- IF li_AppCode < 0 THEN GOTO prcErr
- //关闭存储过程
- CLOSE my_prc;
- return 0
- prcErr:
- rollback;
- messagebox('错误信息',)
复制代码 四、小结
通过前面的三小节内容,相信你已经学会了在PB中怎么执行动态SQL语句?PB怎么调用数据库中存储过程?
PB怎么通过游标对SQL语句查询出的包含多条结果集的处理。这几种场景在PB中都是经常使用的。
以上就是本期的全部内容,希望对你有所帮助 (●'◡'●)
我们下期再见~ ヾ(•ω•`)o
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |