********************************************************************************************** 使用存储过程有以下的优点:
* 存储过程的能力大大增强了SQL语言的功能和灵活性。存储过程可
以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的 运算。
* 可保证数据的安全性和完整性。
# 通过存储过程可以使没有权限的用户在控制之下间接地存取数据 库,从而保证数据的安全。
# 通过存储过程可以使相关的动作在一起发生,从而可以维护数据 库的完整性。
* 再运行存储过程前,数据库已对其进行了语法和句法分析,并给出
了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。 由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执 行。
* 可以降低网络的通信量。
* 使体现企业规则的运算程序放入数据库服务器中,以便: # 集中控制。
# 当企业规则发生变化时在服务器中改变存储过程即可,无须修改
任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运 算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序 工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的 运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可 以了,应用程序无须任何变化。
***************************************************** **************
如何带参数执行SQL的系统储存过程?
问:我想在script中执行Sp_DropUser系统存储过程删除MS SQL Server 7某用户。我是这样写的:execute Sp_DropUser(Sp_DropUser语法),编译提示Sp_DropUser为未定义的系统存储过程。 答:string ls_name ls_name = 'username'
dECLARE dropUser_proc PROCEDURE FOR Sp_DropUser @name_in_db =:ls_name; SQLca.AutoCommit = TRUE EXECUTE dropUser_proc ; SQLca.AutoCommit = false
*************************************************** ORACLE 创建存储过程的语法为:
create [or replace] procedure 过程名
参数1 [in|out|in out] 数据类型
[,参数2 [in|out|in out] 数据类型]... {is|as} pl/sql 语句
create procedure update_log is begin
insert into update_tab(use_name,update_date,operation) values(user,sysdate,'update') end;
然后可在恰当的位置调用这个存储过程来记录用户对表的修改.如在在表SAL_comm上建立一个解发器,
每当用户修改数据库的重要数据时,即把用户的用户名和日期和操作类型记录在表update_tab中
create trigger audit_update after update on sal_comm for each row begin
update_log is end
**************************************** Sybase的存储过程
SYBASE可以用CREATE PROCedure命令生成存储过程: CREATE PROCedure 存储过程名 [;number]
[[(] @parameter_name datatype [=default] [OUTput]
[, @parameter_name datatype [=default] [OUTput]]...[)]] [WITH RECOMPILE] AS SQL_statements
//下面是一个查询作者编码,名称,生日的在、存储过程: create proc p_auths@author_code varchar(10) as
select author,name,birthdate from auths
where author_code=@author_code 下面执行过程
p_auths @author_code=A00001
在CREATE PROC语句中,可以为参数赋缺省值,该值可以是任何常量。 当用户不提供参数值时,该值便作为参数值提供给过程。 *************** pb中使用存储过程:
a.在 DECLARE LOCAL External functions 中声明
<1>.语法一: FUNCTION rtndatype functionname({{REF}datatype1 arg1,......}) RPCFUNC {ALLIAS FOR \<2>.语法二: SUBROUTINE function({{REF}datatype1 arg1,................}} RPCFUNC {ALIAS FOR \
//rtndatatype:说明存储过程的返回值类型; REF:关键字,指明参数以引用方式传递。若少了此字,则以值传递。
RPCFUNC: 关键字,指明该说明是数据库的存储说明,而不是动态链接库的说明。ALIAS FOR \可选项,spname是开发人员为该存储过程起的别名,代码中可以使用。 如:*********声明
FUNCTION double GIVE_RAISE(REF double salary) RPCFUNC ALIAS FOR \
*******************代码中调用 double val=2000 double rv
rv=SQLCA.give_raise_proc(val) b.调用
************************* 在PB中调用存储过程例子
1.在SQL SEVER 数据库后定义存储过程 CREATE PROCEDURE p_cw_hktotal_byclient --按客户统计提货单
@a_com_id char(4),
@a_st_date varchar(256), @a_en_date varchar(256) as begin
select @a_st_date=convert(datetime,@a_st_date) select @a_st_date=convert(datetime,@a_st_date)
--创建统计临时表 create table #salt_total(com_id varchar(4) NOT NULL,client_id varchar(7) NOT NULL,
sl decimal(14,3) NULL,my decimal(14,3) NULL,sy decimal(14,3) NULL,
PRIMARY KEY NONCLUSTERED (com_id,client_id))
--结清
insert into #salt_total select
com_id ,client_id,sum(ord_q),sum(ord_std_mny),sum(ord_real_mny) from salt05
where com_id=@a_com_id and set_date between @a_st_date and @a_en_date
and (bill_typ in('FXTD','FXTH','HZTD')) and upper(ord_stu) = 'Q' group by com_id,client_id
--输出
select com_id,client_id,
sl=case when (sl is null) then 0.00 else sl end,my=case when (my is null) then 0.00 else my end,sy=case when (sy is null) then 0.00 else sy end
from #salt_total
order by com_id,client_id
end GO
2.在PB数据窗口中定义执行语句如下:
execute dbo.p_cw_hktotal_byclient;1 @a_com_id = :a_com_id, @a_st_date = :a_st_date, @a_en_date = :a_en_date
(其中:a_com_id,a_st_date,a_en_date为数据窗口中的参数)
******************************************************************** ORACLE产生数据库触发器的语法为:
create [or replace]trigger 触发器名 触发时间 触发事件 on 表名
[for each row] pl/sql语句
触发器名:触发器对象的名称。由于触发器是数据库自动执行 的,因此该名称只是一个名称,没有实质的用途。 触发时间:指明触发器何时执行,该值可取: before---表示在数据库动作之前触发器执行; after---表示在数据库动作之后出发器执行。
触发事件:指明哪些数据库动作会触发此触发器: insert:数据库插入会触发此触发器; update:数据库修改会触发此触发器; delete:数据库删除会触发此触发器。 表 名:数据库触发器所在的表。
for each row:对表的每一行触发器执行一次。如果没有这一 选项,则只对整个表执行一次。
如下:下面触发器在更新表auths之前触发,目的是不允许在周未修改表 create trigger auth_secure
before insert or update or delete //对整个表更新前触发 on auths begin
if (char(sysdate,'dy')='sun'
raise_applicton_error(-20600,'不能在周未修改表auths\
end if end
******************************************* SYBASE数据库触发器
SYBASE产生触发器的语法为: CREATE TRIGGER 触发器名 ON 表名
FOR INSERT,UPDATE,DELETE AS
SQL_statement | FOR INSERT,UPDATE AS
IF UPDATE(column_name) [AND|OR UPDATE(column_name)]... SQL_statements
上面OR子名用来指定在触发器上的哪些数据更新命令可激活该
触发器。IF UPDATE子句检查对指定列的操作类型,在IF UPDATE子句 中可指定多个列。
与ORACLE不同,对于每条SQL语句,触发器只执行一次。触发器 在数据更新语句完成以后立即执行。触发器和启动它的语句被当作一 个事务处理,事务可以在触发器中回退。 如:create trigger forinsert_books on books for insert as
if (select count(*) from auths,inserted
where auths.author_code=insert.author_code)!=@@rowcount begin
rollback transaction
print \表中 author_code 列的值在auths 表中不存在。\ end
@@@@@@@@@@@@@@@
在PB中调用屏蔽/恢复触发器方式如下: EXECUTE IMMEDIATE \TableName ENABLE TRIGGER\DISABLE TRIGGER\
************************************************************* dw.update({accept{,resetflag}})
//accept:boolean类型,指定数据窗口控件在更新数据库之前是否自动执行accepttext()的功能,并把编辑框中的内容放置到缓冲区中(缺省为true) resetflag:boolean类型,指明更新数据库后是否自动复位更新标志(缺省为true)
******************************************************* relativedate(date,n)
//得到指定日期前多少天或后多少天。
n:integer类型,指定天数返回值Date。当n的值大于0时返回参数date