DBLINK远程从其他实例(库)中获取到值后,给当前过程变量赋值

本文介绍了一种使用PL/SQL动态SQL的方法来通过DBLink进行跨库查询。具体实现方式为构造一条包含DBLink名称的动态SQL语句,并利用EXECUTE IMMEDIATE执行这条语句。

由于dblink_name 是动态获取的所以不能使用

select xxx into xx from table 的写法

改用:

execute immediate 'select to_char(count(1)) from sys_employee@"'||dblink_name||'"' into val_num;

任务描述 本关任务:为 customers 表创建一个存储过程,使该存储过程能通过用户的信用额度来区分用户的等级。 相关知识 为了完成本关任务,你需要掌握: 1.什么是存储过程; 2.存储过程的定义和调用; 3.存储过程编译; 4.存储过程删除。 存储过程简介 在 DM 数据库中,可以在数据库中定义子程序,这种程序块称为存储过程或函数。创建存储过程和函数的好处如下: (1)提供更高的编程效率。在设计应用时,围绕存储过程/函数设计应用,可以避免重复编码;在自顶向下设计应用时,不必关心实现的细节;从 DM7 开始,DM SQL 程序支持全部 C 语言语法,因此在对自定义的 DM SQL 程序语法不熟悉的情况下也可以对数据库进行各种操作,从而可以使对数据库的操作更加灵活,也更加容易。 (2)便于维护。用户的存储模块在数据库中集中存放,用户可以随时对其进行查询、删除,而应用程序可以不作任何修改,或只做少量调整。存储模块能被其他的 DM SQL 程序或 SQL 命令调用,任何客户/服务器工具都能访问 DM SQL 程序,具有很好的可重用性。 (3)提供更好的性能。存储模块在创建时被编译成伪码序列,在运行时不需要重新进行编译和优化处理,具有更快地执行速度,可以同时被多个用户调用,并能够减少操作错误。使用存储模块可减少应用对 DM 的调用,降低系统资源浪费,显著提高性能,尤其是对在网络上与DM通信的应用更显著。 (4)安全性高。存储模块在执行时数据对用户是不可见的,提高了数据库的安全性。可以使用 DM 的管理工具管理存储在服务器中的存储模块的安全性,也可以授权或撤销数据库其他用户访问存储模块的能力。 存储过程的定义和调用 存储过程定义 定义一个存储过程语句的语法格式如下: CREATE [OR REPLACE ] PROCEDURE <模式名.存储过程名> [WITH ENCRYPTION] [(<参数名> <参数模式> <参数数据类型> [<默认表达式>] {,<参数名> <参数模式> <参数数据类型> [<默认表达式>] })] AS | IS [<说明语句端段>] BEGIN <执行语句段> [Exception <异常处理语句段>] END; 其中: (1)<模式名.存储过程名>:指明被创建的存储过程的名称。 (2)<参数名>:指明存储过程参数的名称。 (3) WITH ENCRYPTION:为可选项,如果指定 WITH ENCRYPTION 选项,则对 BEGIN 到 END 之间的语句块进行加密,防止非法用户查看其具体内容,加密后的存储过程或存储函数的定义可在 SYS.SYSTEXTS 系统表中查询。 (4)<参数模式>:指明存储过程参数的输入/输出方式。参数模式可设置为 IN、OUT 或 IN OUT(OUT IN),默认为 IN 类,IN 表示向存储过程传递参数,OUT 表示从存储过程返回参数。而 IN OUT 表示传递参数和返回参数。 (5)<参数数据类型>:指明存储过程参数的数据类型。 (6)<说明语句端段>:由变量、游标和子程序等对象的申明构成。 (7)<执行语句段>:由 SQL 语句和过程控制语句构成的执行代码。 (8)<异常处理语句段>:各种异常的处理程序,存储过程执行异常时调用,可默认。 注意:使用该语句的用户必须是 DBA 或该存储过程的拥有者且具有 CREATE PROCEDURE 数据库权限的用户;参数的数据类型只能指定变量类型,不能指定长度。 【例1】创建一个简单的带参数的存储过程 PROC_1。 CREATE OR REPLACE PROCEDURE PROC_1(a IN OUT INT) AS b INT; BEGIN a:=a+b; EXCEPTION WHEN OTHERS THEN NULL; END; 在此例中第 2 行是该存储过程的说明部分,这里申明了一个变量 b。第 4 行是该程序块运行时执行语句码段,这里将 a 与 b 的和赋给参数 a。如果发生了异常,第 5 行开始的异常处理部分就对产生的异常情况进行处理,WHEN OTHERS 异常处理器处理所有不被其他异常处理器处理的异常。 存储过程的调用 存储模块可以被其他存储模块或应用程序调用。同样,在存储模块中也可以调用其他存储模块。调用存储过程时,应给存储过程提供输入参数,并获取存储过程的输出参数。调用的语法格式如下: [CALL] [<模式名>.]<存储过程名> [@dblink_name][(<参数1>{, <参数2>})]; 其中: (1)<模式名>:指明被调用存储过程所属的模式。 (2)<存储过程名>:指明被调用存储过程的名称。 (3)“dblink_name”表示创建的 dblink 名字,如果添加了该选项,则表示调用远程实例的存储模块。 (4)<参数>:指明提供给存储过程的参数。 使用说明如下: (1)如果被调用的存储过程不属于当前模式,必须在语句中指明存储过程的模式名。 (2)参数的个数和类型必须与被调用的存储过程一致。 (3)存储过程的输入参数可以是嵌入式变量,也可以是表达式;存储过程的输出参数必须是可赋值对象,如嵌入式变量。 (4)执行该操作的用户必须拥有该存储过程的 EXECUTE 权限。存储过程的所有者和DBA用户隐式具有该过程的 EXECUTE 权限,该权限也可通过授权语句显式授予其他用户。所有用户都可调用自己创建的存储过程,如果要调用其他用户的存储过程,则需要对该存储过程具有 EXECUTE 权限,即存储过程的所有者将 EXECUTE 权限授予该用户。授予 EXECUTE 权限的语法如下: GRANT EXECUTE ON 过程名 TO 用户; 【例2】存储过程的调用。以用户 SYSDBA 的身份创建存储过程 p1。 CREATE OR REPLACE PROCEDURE p1(a IN OUT INT) AS v1 INT:=a; BEGIN a:=0; FOR B IN 1 .. V1 LOOP a:=a+b; END LOOP; END; 在存储过程 P2 中调用存储过程 P1。 CREATE OR REPLACE PROCEDURE P2(a IN INT) AS v1 INT :=a; BEGIN P1(v1); PRINT v1; END; 【例3】按参数名调用存储过程。创建存储过程 P1。 CREATE OR REPLACE PROCEDURE P1(a INT, b IN OUT INT) AS v1 INT:=a; BEGIN b:=0; FOR C IN 1 .. V1 LOOP b:=b+c; END LOOP; END; 在存储过程 P2 中以按参数名方式调用过程 P1。 CREATE OR REPLACE PROCEDURE P2(a IN INT) AS v1 INT :=a; v2 INT; BEGIN P1(b=v2, a=v1); PRINT v2; END; 【例4】DBLINK 调用远程实例的存储模块举例。 1.假设远程数据库实例名 dmserver2,端口号 5237)已创建 DBLINK,名为 TEST_LINK。该远程数据库上存在存储过程 dm_get_next_val。 CREATE OR REPLACE PROCEDUREdm_get_next_val(a IN OUT INT) AS BEGIN a := a + 1; END; 2.在本地(实例名 dmserver,端口号 5236)通过 DBLINK 名字TEST_LINK,调用上述远程过程。 DECLARE x INT; BEGIN x := 1; dm_get_next_val@TEST_LINK(x); PRINT x; END; 存储过程应用实例 【例5】设计一个不带参数存储过程 p_salarysum_ bycityname,统计公司在各大城市的员工工资之和,并显示各城市名称和工资总数。 CREATE OR REPLACE PROCEDURE p_salarysum_bycityname AS CURSOR city_cursor IS SELECT region_id,city_id,city_name FROM city ORDER BY region_id; v_salarysum number(10,2); BEGIN FOR city_rec IN city_cursor LOOP SELECT SUM(a.salary) INTO v_salarysum FROM employee a WHERE a.department_id IN (SELECT department_id FROM DEPARTMENT WHERE location_id=city_rec.region_id); PRINT city_rec.city_name||','||v_salarysum; END LOOP; END; 【例6】设计一个带参数存储过程 p_salarysum_bycityname (v_cityname IN varchar2, salarysum OUT number),参数是城市名称和输出参数工资总数,根据输入的城市名称统计所属员工的工资之和,并显示各城市名称和工资总数。 CREATE OR REPLACE PROCEDURE p_salarysum_bycityname(v_cityname IN varchar2, salarysum OUT number) AS v_salarysum number(10,2); v_region_id number; BEGIN SELECT region_id INTO v_region_id FROM city WHERE city_name=v_cityname; SELECT SUM(a.salary) INTO v_salarysum FROM employee a WHERE a.department_id IN (SELECT department_id FROM DEPARTMENT WHERE location_id=v_region_id); PRINT v_cityname||','||v_salarysum; salarysum:= v_salarysum; EXCEPTION WHEN NO_DATA_FOUND THEN PRINT '在该城市没有员工'; END; 注意:在定义带参数的存储过程时,注意在存储过程名称后的参数的数据类型,不要定义参数数据类型的长度,否则会出错。 在 DM SQL 中调用存储过程 p_salarysum_bycityname 的方法如下: DECLARE v_salary NUMBER(10,2); BEGIN p_salarysum_bycityname('上海',v_salary); PRINT v_salary; END; 存储过程编译 在存储过程中会用到一些表、索引等对象,这些对象可能已经被修改或者被删除,这就意味着存储过程可能已经失效了。当用户需要调用存储模块时,先重新编译一下该存储模块,用来判断在当前情况下,存储模块是否可用。重新编译一个存储过程的语法格式如下: ALTER PROCEDURE <存储过程名> COMPILE [DEBUG]; 【例7】重新编译存储过程p_salarysum_bycityname。 ALTER PROCEDURE p_salarysum_bycityname COMPILE; 存储过程删除 当用户需要从数据库中删除一个存储模块时,可以使用存储模块删除语句。其语法如下: DROP PROCEDURE <存储过程名定义>; 使用说明:如果被删除的存储过程不属于当前模式,必须在语句中指明过程的模式名。执行该操作的用户必须是该存储过程的拥有者,或者具有 DBA 权限。 【例8】删除存储过程 p_salarysum_bycityname。 DROP PROCEDURE p_salarysum_bycityname; 编程要求 根据提示,在右侧编辑器补充代码,创建存储过程getcustomerlevel(v_customNumber in int, v_customerLevel out varchar2),通过查询 customers 表中客户的信用额度,来决定客户级别,并将客户编号和对应等级输出,具体输出内容参考测试集。 customers 表数据结构: customerNumber creditlimit 101 2000 102 12000 103 6000 等级设定: PLATINUM (creditlim>10000) GOLD (5000<=creditlim<=10000) SILVER(creditlim<5000) -- 请在此编写sql语句 ---------- Begin ---------- create or replace produce getcustomerlevel(v_customNumber in int, v_customerLevel out varchar2) as v_customNumber number(10,2); v_region_id number; Begin select region_id into v_region_id from ---------- End ---------- -- 请勿删除下面语句 / exit
最新发布
11-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值