Oracle_SP

#分割字符串
create or replace procedure sp_string(v_string in varchar2)
 as
  /*author:xuguoqi
  time:  2018-12-10
  usage: 输入一个以逗号分割的字符串,输出分割后的结果 如 输入:aa,bb,cc
                                                        输出:aa
                                                             bb
                                                             cc
                                                       
  */
  v_array dbms_utility.lname_array;
  v_tab binary_integer;
  v_list varchar(100):=v_string;
  valid_string exception;
  begin
   if instr(v_list,',')<=0 then 
     raise valid_string;
   else  
     dbms_utility.comma_to_table(list=>v_list,tab=>v_array,tablen=>v_tab);
      for i in 1..v_tab loop
        dbms_output.put_line(v_array(i));
       end loop;
   end if;
   exception 
           when valid_string then 
              dbms_output.put_line('只能以逗号作为分隔符,如 aa,bb,cc,dd');
           when others then 
              dbms_output.put_line(sqlerrm);
  end;
  


#util_file包的使用

create or replace directory dir2 as '/home/oracle/utlfile';
grant read,write on directory dir2 to scott;
grant execute on utl_file to scott;



create or replace procedure utl_file_use(v_str in varchar2,v_filename in varchar2)
as
/*author:xuguoqi
  time:  2018-12-10
  usage: 输入一个sql语句,在服务器上面生成一个文件
  */
 file_type utl_file.file_type;               --定义file_type
 v_dir_name varchar2(100) default 'DIR2';    --dirname
 v_check_dir varchar2(20);                   --检查dir的是否存在
 invalid_directory exception;                --定义异常
 file_name varchar2(100):=to_char( current_timestamp,'yyyymmddhh24miss');         --定义filename为时间.txt
 type v_recoed is table of varchar(4000);    --定义一个table type
 v_rc v_recoed;
 v_cur sys_refcursor;                        --声明一个游标
begin
     select nvl(DIRECTORY_NAME,'0') into v_check_dir from dba_directories where DIRECTORY_NAME=v_dir_name;
     if v_check_dir='0' then
       raise invalid_directory;
     else
         file_name :=file_name||'_ '||v_filename||'.txt';
        
         file_type :=utl_file.fopen(v_dir_name,file_name,'W',1000);         
                open v_cur for v_str;
                loop 
                  exit when v_cur%notfound;
                   fetch v_cur bulk collect into v_rc;
                    for i in v_rc.first..v_rc.last loop                                                    
                             utl_file.put_line(file_type,v_rc(i));
                    end loop;
                end loop; 
                close v_cur;         
     end if;
     utl_file.fflush(file_type);
     utl_file.fclose(file_type);
    exception 
             when invalid_directory then
                  dbms_output.put_line('检查输入的directory是否存在或者是否授予访问 读写权限');
             when others then
                  dbms_output.put_line(sqlerrm);
end;


运行结果:
[oracle@oracle utlfile]$ more 20181130113724_emp.txt
7369,SMITH,CLERK
7499,ALLEN,SALESMAN
7521,WARD,SALESMAN
7566,JONES,MANAGER
7654,MARTIN,SALESMAN
7698,BLAKE,MANAGER
7782,CLARK,MANAGER
7839,KING,PRESIDENT
7844,TURNER,SALESMAN
7876,ADAMS,CLERK
7900,JAMES,CLERK
7902,FORD,ANALYST
7934,MILLER,CLERK



create or replace type str is table of varchar(50);
/


CREATE OR REPLACE FUNCTION random_strings (v_number IN INTEGER

)
/*author:xuguoqi
  生成长度为10的随机字符串
*/
   RETURN str
   AUTHID CURRENT_USER
IS
    string str := str();
BEGIN
    string.EXTEND (v_number);

   FOR indx IN 1 .. v_number
   LOOP
      string(indx) := DBMS_RANDOM.string ('u', 10);
   END LOOP;

   RETURN string;
END;



#把查询结果转换为列名
create table ass(acptnum varchar(30),qu_name varchar(4000),awname varchar(2000));


insert into ass values('15101232097','问题1','答案1');
insert into ass values('15101232097','问题2','答案2');
insert into ass values('15101232097','问题3','答案3');
insert into ass values('18290890601','x','x');
insert into ass values('18290890601','x1','x2');
insert into ass values('18290890601','x2','x2');
insert into ass values('18290890601','x3','x3');

select * from ass;
  acptnum     qu_name   awname                  
1	15101232097	问题1	    答案1
2	15101232097	问题2	    答案2
3	15101232097	问题3	    答案3
4	18290890601	x	        x
5	18290890601	x1	      x2
6	18290890601	x2	      x2
7	18290890601	x3	      x3


         
create or replace procedure exeute_select(v_out out sys_refcursor)
as
/*把列值转换为列名*/
c1    sys_refcursor;
v_sql VARCHAR(1000):='';
c2 ass.qu_name%type;
BEGIN
       v_sql:='select acptnum';
       open c1 for select distinct qu_name from ass;
       loop
         fetch c1 into c2;
         
         exit when c1%notfound;
         
         v_sql :=v_sql||',max(case qu_name when  '''||c2||'''   then  awname else null end ) as ' ||c2;
         
       end loop;
         close c1;
         
           v_sql :=v_sql|| ' from ass group by acptnum';
           
           open v_out for v_sql;           
  END;  


#实现效果

address    name   color

北京       苹果   绿色

北京       香蕉   黄色

北京       葡萄   紫色


address     苹果   香蕉  葡萄

北京        绿色   黄色  紫色



#parallel

oracle 批量更新大表:

select task_name,chunk_type,status from dba_parallel_execute_tasks;

grant create job to SCOTT; 
grant execute on dbms_scheduler to SCOTT;
grant execute on dbms_parallel_execute to SCOTT;


CREATE OR REPLACE PROCEDURE PARALLEL_SQL
authid current_user
AS
  l_sql_stmt VARCHAR2(1000);
  l_try NUMBER;
  l_status NUMBER;
  v_start number;
  v_end  number;
  v_task_name varchar2(100):='xugq';
  v_table_owner varchar2(100) :='SCOTT';
  v_table_name varchar2(100) :='LFN_TASK_TEST';
BEGIN
	/*如果 CREATE_CHUNKS_BY_ROWID 必须写 where rowid between :start_id and :end_id*/
  l_sql_stmt := 'UPDATE /*+ rowid (dda) */ LFN_TASK_TEST SET SAL=18000 where rowid between :start_id and :end_id';
  v_start :=dbms_utility.get_time;
  DBMS_PARALLEL_EXECUTE.CREATE_TASK (v_task_name);
  DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID(v_task_name,v_table_owner,v_table_name, true, 100);
  
  DBMS_PARALLEL_EXECUTE.RUN_TASK(v_task_name,l_sql_stmt,DBMS_SQL.NATIVE,parallel_level => 1);
  l_try := 0;
  l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS(v_task_name);
  WHILE(l_try < 2 and (l_status != DBMS_PARALLEL_EXECUTE.FINISHED)) 
  LOOP
    l_try := l_try + 1;
    DBMS_PARALLEL_EXECUTE.RESUME_TASK(v_task_name);
    l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS(v_task_name);
  END LOOP;
  DBMS_PARALLEL_EXECUTE.DROP_TASK(v_task_name);
  v_end :=dbms_utility.get_time;
  DBMS_OUTPUT.PUT_LINE('执行时间:'||to_char(v_end-v_start));  
  commit;
        exception
                when others then
                     DBMS_PARALLEL_EXECUTE.DROP_TASK(v_task_name);
                     DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;



#建立job 执行job 删除job 停止job.


create or replace package action_job
as
 procedure create_job;
 procedure run_job(v_job_name in number);
 procedure drop_job(v_job in number);
 procedure stop_job(v_stop_num_job number);
 procedure select_info_job(v_out out sys_refcursor);
end;

create or replace package body action_job
as
  /*新建一个Job*/
  procedure create_job
    is
       v_job_num number;               --定义job号
       v_what varchar2(150):='utl_file_use';              --要执行的sp或者函数
       v_next_date varchar2(100):='2018-12-12 18:00:00';  --第一次执行的时间
       v_interval  varchar2(100):='sysdate+1/24';  --执行时间间隔
       /*example interval=sysdate+1/24         每隔一小时
                 interval=sysdate+1/(24*60*60) 每秒钟运行一次
                 interval=sysdate+1/(24*60)    每分钟运行一次
                 interval=last_day(sysdate)+1+1/24 没月凌晨一点执行
                 interval=trunc(next_day(sysdate,'Mon'))+1/24
       
       */
       begin
           dbms_job.submit(job=>v_job_num,
                           what=>v_what||';',
                           next_date => to_date(v_next_date,'yyyy-mm-dd hh24:mi:ss'),
                           interval=>v_interval
                           );
       dbms_output.put_line('the job number is:'||v_job_num);
       end;
   /*删除Job*/
   procedure drop_job(v_job in number)
      is
      drop_num number:=v_job;     
      begin
         dbms_job.remove(drop_num);
         dbms_output.put_line('job'||drop_num||'has been deleted');
         exception 
                  when others then
                    dbms_output.put_line('please input a validate job number');
      end;
    /*运行Job*/  
    procedure run_job(v_job_name in number)
      is
      begin
           dbms_job.run(v_job_name);
           exception 
                   when others then
                     dbms_output.put_line(sqlerrm);
      end;  
    /*停止Job*/
    procedure stop_job(v_stop_num_job number)
      is
      v_broken boolean:=True;
      begin
           dbms_job.broken(v_stop_num_job,broken => v_broken);
             exception
                      when others then
                        dbms_output.put_line(sqlerrm);
      end;
      
      /*查询job相关信息*/
      procedure select_info_job(v_out out sys_refcursor)
        is 
          begin
               open v_out for select * from user_jobs;
          end;
          
                       
end action_job;



Oracle with字句:
with e as (select * from emp),
     d as (select * from dept)
 select e.ename,d.dname from e,d 
  where e.empno=7369 and d.deptno=20;


ENAME      DNAME
---------- --------------
SMITH      RESEARCH


with t(a,b) as (select 1,2 from dual)
select t.a from t;


#



declare
  type c1 is table of indeic_test.name%type index by pls_integer;
  c2 c1;
 begin
 	   c2(1):='lfn';
 	   c2(10):='xugq';
 	   forall i_index in indices of c2
 	       update indeic_test set num=12
 	       where name=c2(i_index);
 	   dbms_output.put_line(sql%rowcount);
 end;
 /

SCOTT@PROD>select * from indeic_test;

NAME              NUM
---------- ----------
lfn                12
xugq               12
bei               500
shen              900


declare
  type c1 is table of indeic_test.name%type index by pls_integer;
  c2 c1;
  type c3 is table of boolean index by pls_integer;
  c4 c3;
 begin
 	   c2(1):='lfn';
 	   c2(10):='xugq';
 	   c2(12):='null';
 	   c4(1) :=FALSE;
 	   c4(10):=TRUE;
 	   c4(12):=null;
 	   forall i_index in indices of c4 between 1 and 30
 	       update indeic_test set num=18
 	       where name=c2(i_index);
 	   dbms_output.put_line(sql%rowcount);
 end;
 /
 
 
#insert all 
insert all 
  into indeic_test(name,num)
  into indeic_test(name,num)
  select 'ab',1 from dual;




declare
   type my_table_type is table of integer;
   t1   my_table_type := my_table_type(1,2,3,4);
   t2   my_table_type := my_table_type(2,4,4,5);
   s    integer;
begin
   for i in 1..t1.count loop
      s := t1(i) + t2(i);
      if not mod(s,2)=1 then
         continue;
      end if;
      dbms_output.put_line(t1(i)||''||t2(i));
      dbms_output.put_line(s);
   end loop;
end;
/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值