参考资料:这里写链接内容
游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。
Cursor类型包含三种: 隐式Cursor,显式Cursor和Ref Cursor(动态Cursor)。
1. 隐式Cursor:
1).对于Select …INTO…语句,一次只能从数据库中获取到一条数据,对于这种类型的DML Sql语句,就是隐式Cursor。例如:Select /Update / Insert/Delete操作。
2)作用:可以通过隐式Cusor的属性来了解操作的状态和结果,从而达到流程的控制。Cursor的属性包含:
SQL%ROWCOUNT 整型 代表DML语句成功执行的数据行数
SQL%FOUND 布尔型 值为TRUE代表插入、删除、更新或单行查询操作成功
SQL%NOTFOUND 布尔型 与SQL%FOUND属性返回值相反
SQL%ISOPEN 布尔型 DML执行过程中为真,结束后为假
3) 隐式Cursor是系统自动打开和关闭Cursor.
下面是一个Sample:
Set Serveroutput on;
begin update t_contract_master set liability_state = 1 where policy_code = '123456789';
if SQL%Found then
dbms_output.put_line('the Policy is updated successfully.');
commit;
else
dbms_output.put_line('the policy is updated failed.');
end if;
end;
/
Set Serveroutput on;
begin update t_contract_master set liability_state = 1 where policy_code = '123456789';
if SQL%Found then
dbms_output.put_line('the Policy is updated successfully.');
commit;
else
dbms_output.put_line('the policy is updated failed.');
end if;
end;
/
在PL/SQL中run:
SQL>
the policy is updated failed.
PL/SQL procedure successfully completed [SQL] view plain copy SQL> the policy is updated failed. PL/SQL procedure successfully completed
(1) 对于从数据库中提取多行数据,就需要使用显式Cursor。显式Cursor的属性包含:
游标的属性 返回值类型 意 义
%ROWCOUNT 整型 获得FETCH语句返回的数据行数
%FOUND 布尔型 最近的FETCH语句返回一行数据则为真,否则为假
%NOTFOUND 布尔型 与%FOUND属性返回值相反
%ISOPEN 布尔型 游标已经打开时值为真,否则为假
(2) 对于显式游标的运用分为四个步骤:
定义游标—Cursor [Cursor Name] IS;
打开游标—Open [Cursor Name];
操作数据—Fetch [Cursor name]
关闭游标—Close [Cursor Name],这个Step绝对不可以遗漏。
(3)以下是三种常见显式Cursor用法。
1)
Set serveroutput on;
declare
---define Cursor
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm where cm.liability_state = 2 and cm.policy_type = 1 and cm.policy_cate in ('2','3','4') and rownum < 5 order by cm.policy_code desc;
curPolicyInfo cur_policy%rowtype;---定义游标变量
Begin open cur_policy; ---open cursor
Loop
--deal with extraction data from DB
Fetch cur_policy into curPolicyInfo;
Exit when cur_policy%notfound;
Dbms_Output.put_line(curPolicyInfo.policy_code);
end loop;
Exception
when others then
close cur_policy;
Dbms_Output.put_line(Sqlerrm);
if cur_policy%isopen then
--close cursor
close cur_policy;
end if;
end;
/
Set serveroutput on;
declare
---define Cursor
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm where cm.liability_state = 2 and cm.policy_type = 1 and cm.policy_cate in ('2','3','4') and rownum < 5 order by cm.policy_code desc;
curPolicyInfo cur_policy%rowtype;---定义游标变量
Begin open cur_policy; ---open cursor
Loop
--deal with extraction data from DB
Fetch cur_policy into curPolicyInfo;
Exit when cur_policy%notfound;
Dbms_Output.put_line(curPolicyInfo.policy_code);
end loop;
Exception
when others then
close cur_policy;
Dbms_Output.put_line(Sqlerrm);
if cur_policy%isopen then
--close cursor
close cur_policy;
end if;
end;
/
2)
Set serveroutput on;
declare
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
from t_contract_master cm
where cm.liability_state = 2
and cm.policy_type = 1
and cm.policy_cate in ('2','3','4')
and rownum < 5
order by cm.policy_code desc;
v_policyCode t_contract_master.policy_code%type;
v_applicantId t_contract_master.applicant_id%type;
v_periodPrem t_contract_master.period_prem%type;
v_bankCode t_contract_master.bank_code%type;
v_bankAccount t_contract_master.bank_account%type;
Begin
open cur_policy;
Loop
Fetch cur_policy into v_policyCode,
v_applicantId,
v_periodPrem,
v_bankCode,
v_bankAccount;
Exit when cur_policy%notfound;
Dbms_Output.put_line(v_policyCode);
end loop;
Exception
when others then
close cur_policy;
Dbms_Output.put_line(Sqlerrm);
if cur_policy%isopen then
close cur_policy;
end if;
end;
/
Set serveroutput on;
declare
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
from t_contract_master cm
where cm.liability_state = 2
and cm.policy_type = 1
and cm.policy_cate in ('2','3','4')
and rownum < 5
order by cm.policy_code desc;
v_policyCode t_contract_master.policy_code%type;
v_applicantId t_contract_master.applicant_id%type;
v_periodPrem t_contract_master.period_prem%type;
v_bankCode t_contract_master.bank_code%type;
v_bankAccount t_contract_master.bank_account%type;
Begin
open cur_policy;
Loop
Fetch cur_policy into v_policyCode,
v_applicantId,
v_periodPrem,
v_bankCode,
v_bankAccount;
Exit when cur_policy%notfound;
Dbms_Output.put_line(v_policyCode);
end loop;
Exception
when others then
close cur_policy;
Dbms_Output.put_line(Sqlerrm);
if cur_policy%isopen then
close cur_policy;
end if;
end;
/
3)
Set serveroutput on;
declare
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm where cm.liability_state = 2 and cm.policy_type = 1 and cm.policy_cate in ('2','3','4') and rownum < 5 order by cm.policy_code desc;
Begin For rec_Policy in cur_policy loop Dbms_Output.put_line(rec_policy.policy_code);
end loop;
Exception
when others then
Dbms_Output.put_line(Sqlerrm);
end;
/
Set serveroutput on;
declare
Cursor cur_policy is
select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm where cm.liability_state = 2 and cm.policy_type = 1 and cm.policy_cate in ('2','3','4') and rownum < 5 order by cm.policy_code desc;
Begin For rec_Policy in cur_policy loop Dbms_Output.put_line(rec_policy.policy_code);
end loop;
Exception
when others then
Dbms_Output.put_line(Sqlerrm);
end;
/
run pl/sql,执行结果如下:
SQL>
8780203932
8780203227
8780203218
8771289268
PL/SQL procedure successfully completed [sql] view plain copy SQL> 8780203932 8780203227 8780203218 8771289268 PL/SQL procedure successfully completed
1) 与隐式Cursor,显式Cursor的区别:Ref Cursor是可以通过在运行期间传递参数来获取数据结果集。而另外两种Cursor,是静态的,在编译期间就决定数据结果集。
2) Ref cursor的使用:
Type [Cursor type name] is ref cursor
Define 动态的Sql语句
Open cursor
操作数据—Fetch [Cursor name]
Close Cursor
下面是一个Sample:
Set serveroutput on;
Declare
---define cursor type name
type cur_type is ref cursor;
cur_policy cur_type;
sqlStr varchar2(500);
rec_policy t_contract_master%rowtype;
begin
---define 动态Sql
sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm
where cm.liability_state = 2
and cm.policy_type = 1
and cm.policy_cate in (2,3,4)
and rownum < 5
order by cm.policy_code desc ';
---Open Cursor
open cur_policy for sqlStr;
loop
fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;
exit when cur_policy%notfound;
Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);
end loop;
close cur_policy;
end;
/
Set serveroutput on;
Declare
---define cursor type name
type cur_type is ref cursor;
cur_policy cur_type;
sqlStr varchar2(500);
rec_policy t_contract_master%rowtype;
begin
---define 动态Sql
sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm
where cm.liability_state = 2
and cm.policy_type = 1
and cm.policy_cate in (2,3,4)
and rownum < 5
order by cm.policy_code desc ';
---Open Cursor
open cur_policy for sqlStr;
loop
fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;
exit when cur_policy%notfound;
Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);
end loop;
close cur_policy;
end;
/
对数据库有写操作(INSERT、UPDATE、DELETE、CREATE、ALTER、COMMIT)的函数,是无法简单的用SQL来调用的.
解决办法如下,只需在声明中添加 PRAGMA AUTONOMOUS_TRANSACTION
CREATE OR REPLACE FUNCTION FUN_SET_PROJECT_COST ( V_BUDGET_OBJECT_ID IN VARCHAR2, V_ADJUST_ID IN VARCHAR2 ) RETURN VARCHAR2;
IS
PRAGMA AUTONOMOUS_TRANSACTION;
CREATE OR REPLACE FUNCTION FUN_SET_PROJECT_COST ( V_BUDGET_OBJECT_ID IN VARCHAR2, V_ADJUST_ID IN VARCHAR2 );
RETURN VARCHAR2;
IS
PRAGMA AUTONOMOUS_TRANSACTION;
END;
PRAGMA AUTONOMOUS_TRANSACTION自治事务
当前的存储过程作为已有事务的子事务运行,子事务的commit,rollback操作不影响父事务的状态
在你的一个事务(外层事务)中可以定义一个或几个自治事务。自治事务可以独立commit,不对外层事务产生影响,同样外层事务的 rollback 也对自治事务没有影响。通常可以考虑将自治事务定义成一个过程,在外层的事务中调用。
1、去掉重复记录 保留一条
DELETE FROM A_TEST
WHERE UNAME IN ( SELECT UNAME
FROM A_TEST
GROUP BY UNAME
HAVING COUNT(UNAME) > 1 )
AND ROWID NOT IN ( SELECT MIN(ROWID)
FROM A_TEST
GROUP BY UNAME
HAVING COUNT(UNAME) > 1 )
2、替换字段根据指定的字符
update QF_KEYWORDS set KEYWORD=REPLACE(KEYWORD, ‘,’ , ”)
3、oracle job时间
每天运行一次 ‘SYSDATE + 1’
每小时运行一次 ‘SYSDATE + 1/24’
每10分钟运行一次 ‘SYSDATE + 10/(60*24)’
每30秒运行一次 ‘SYSDATE + 30/(60*24*60)’
每隔一星期运行一次 ‘SYSDATE + 7’
每天午夜12点 ‘TRUNC(SYSDATE + 1)’
每天早上8点30分 ‘TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)’
每星期二中午12点 ‘NEXT_DAY(TRUNC(SYSDATE ), ”TUESDAY” ) + 12/24’
每个月第一天的午夜12点 ‘TRUNC(LAST_DAY(SYSDATE ) + 1)’
每个季度最后一天的晚上11点 ‘TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), ‘Q’ ) -1/24’
每星期六和日早上6点10分 ‘TRUNC(LEAST(NEXT_DAY(SYSDATE, ”SATURDAY”), NEXT_DAY(SYSDATE, “SUNDAY”))) + (6×60+10)/(24×60)’
每天凌晨0点执行
TRUNC(sysdate+1)
每天凌晨1点执行
TRUNC(sysdate+1)+1/24
每天早上8点30分执行
TRUNC(SYSDATE+1)+(8*60+30)/(24*60)
3、每周定时执行
例如:
每周一凌晨2点执行
TRUNC(next_day(sysdate,1))+2/24
TRUNC(next_day(sysdate,’星期一’))+2/24
每周二中午12点执行
TRUNC(next_day(sysdate,2))+12/24
TRUNC(next_day(sysdate,’星期二’))+12/24
4、每月定时执行
例如:
每月1日凌晨0点执行
TRUNC(LAST_DAY(SYSDATE)+1)
每月1日凌晨1点执行
TRUNC(LAST_DAY(SYSDATE)+1)+1/24
5、每季度定时执行
每季度的第一天凌晨0点执行
TRUNC(ADD_MONTHS(SYSDATE,3),’q’)
每季度的第一天凌晨2点执行
TRUNC(ADD_MONTHS(SYSDATE,3),’q’)+2/24
每季度的最后一天的晚上11点执行
TRUNC(ADD_MONTHS(SYSDATE+ 2/24,3),’q’)-1/24
6、每半年定时执行
例如:
每年7月1日和1月1日凌晨1点执行
ADD_MONTHS(TRUNC(sysdate,’yyyy’),6)+1/24
7、每年定时执行
例如:
每年1月1日凌晨2点执行
ADD_MONTHS(TRUNC(sysdate,’yyyy’),12)+2/24
根据规律来算,其实就非常简单了。
4、oracle查询表名:
select table_name from all_tables t where table_name like ‘%SEND%’
当库中的表中太多太多的时候,可以查询所有库中的表名
5、创建索引:
CREATE INDEX “IPIQXT”.”TZHS10_SUBMIT” ON “IPIQXT”.”TZHS10_SUBMIT”
(
“ID”
)
PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS STORAGE
(
INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT
)
TABLESPACE “MBOP” ;
–两种方法 三十分钟执行一次存储过程DAYBAKDATA
1、VARIABLE jobno number;
BEGIN
DBMS_JOB.SUBMIT(:jobno, ‘DAYBAKDATA;’, sysdate , ‘SYSDATE+30/1440’);
commit;
END;
2、DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
( job => X
,what => ‘DAYBAKDATA;’
,next_date => SYSDATE+30/1440
,interval => ‘SYSDATE+30/1440’
,no_parse => FALSE
);
SYS.DBMS_OUTPUT.PUT_LINE(‘Job Number is: ’ || to_char(x));
COMMIT;
7、打印
dbms_output.put_line(‘归档了一条彩信发送状态’);
8、创建索引:
CREATE INDEX “MY_SUBMIT4” ON “MY_SUBMIT4”
(
“ID”
)
10、创建触发器
create or replace
TRIGGER bjcbsend
AFTER INSERT ON a_SUBMIT
FOR EACH ROW
DECLARE
BEGIN
–sql操作 以上是插入数据时候的触发器 以下注释的是如果你想要修改某个字段的时候的触发器 只需把INSERT改成UPDATE 然后加上以下代码
– if updating(‘字段’) and :NEW.字段> ‘100’ then
– 执行sql操作
– end if;
–END;
9、创建序列
CREATE SEQUENCE “IPIQXT”.”SEQ_ABLEPHOTO”
MINVALUE 1 MAXVALUE 9999999999999999999999999999
INCREMENT BY 1 START WITH 20000 CACHE 20 NOORDER NOCYCLE ;
10、创建函数
–从表T_a 中取出phone 条件是AREANO =传入的参数areano1
create or replace
function vphone (areano1 in varchar2)
return varchar2
is
phone1 varchar2(20);
begin
select phone into phone1 from T_a where rownum=1 and AREANO = areano1 and flag
return(phone1);
end ;