【数据库摘要】12_Sql_存储过程

SQL 存储过程

存储过程创建语法:

create or replace procedure 存储过程名(param1 in type,param2 out type)
as
    变量1 类型(值范围); --vs_msg   VARCHAR2(4000);
    变量2 类型(值范围);
Begin
    Select count(*) into 变量1 from 表A where列名=param1;
    If (推断条件) then
        Select 列名 into 变量2 from 表A where列名=param1。
        Dbms_output。Put_line(‘信息打印’);
    Elsif (推断条件) then
        Dbms_output。Put_line(‘信息打印’);
    Else
       Raise 异常名(NO_DATA_FOUND);
    End if;
    Exception
        When others then
        Rollback;
End;

注意事项:

  • 存储过程參数不带取值范围,in表示传入,out表示输出 类型能够使用随意Oracle中的合法类型。
  • 变量带取值范围。后面接分号
  • 在推断语句前最好先用count(*)函数推断是否存在该条操作记录
  • 用select 。

    。。into。

    。。

    给变量赋值

  • 在代码中抛异经常使用 raise+异常名

实例

CREATE OR REPLACE PROCEDURE存储过程名
    (
    --定义參数
    is_ym  IN CHAR(6) ,
    the_count OUT NUMBER,
    )
AS
    --定义变量
    vs_msg   VARCHAR2(4000);   --错误信息变量
    vs_ym_beg  CHAR(6);      --起始月份
    vs_ym_end  CHAR(6);      --终止月份
    vs_ym_sn_beg CHAR(6);     --同期起始月份
    vs_ym_sn_end CHAR(6);     --同期终止月份
    --定义游标(简单的说就是一个能够遍历的结果集)
    CURSOR cur_1 IS
    SELECT 。。

。
    FROM 。。。
    WHERE 。。。
    GROUP BY 。

。。

;
BEGIN
    --用输入參数给变量赋初值。用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等非经常常使用的函数。
    vs_ym_beg := SUBSTR(is_ym,1,6);
    vs_ym_end := SUBSTR(is_ym,7,6);
    vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,‘yyyymm‘), -12),‘yyyymm‘);
    vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,‘yyyymm‘), -12),‘yyyymm‘);
    --先删除表中特定条件的数据。
    DELETE FROM 表名 WHERE ym = is_ym;
    --然后用内置的DBMS_OUTPUT对象的put_line方法打印出影响的记录行数,当中用到一个系统变量SQL%rowcount
    DBMS_OUTPUT.put_line(‘del上月记录=‘||SQL%rowcount||‘条‘); 

    INSERT INTO表名(area_code,ym,CMCODE,rmb_amt,usd_amt)
    SELECT area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
    FROM BGD_AREA_CM_M_BASE_T
    WHERE ym >= vs_ym_beg
    AND ym <= vs_ym_end
    GROUP BY area_code,CMCODE; 

    DBMS_OUTPUT.put_line(‘ins当月记录=‘||SQL%rowcount||‘条‘);
    --遍历游标处理后更新到表。遍历游标有几种方法,用for语句是当中比較直观的一种。
    FOR rec IN cur_1 LOOP
        UPDATE 表名
        SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
        WHERE area_code = rec.area_code
        AND CMCODE = rec.CMCODE
        AND ym = is_ym;
    END LOOP;
    COMMIT; 

    --错误处理部分。OTHERS表示除了声明外的随意错误。SQLERRM是系统内置变量保存了当前错误的具体信息。
    EXCEPTION
        WHEN OTHERS THEN
            vs_msg := ‘ERROR IN xxxxxxxxxxx_p(‘||is_ym||‘):‘||SUBSTR(SQLERRM,1,500);
    ROLLBACK;
    --把当前错误记录进日志表。
    INSERT INTO LOG_INFO(proc_name,error_info,op_date)
        VALUES(‘xxxxxxxxxxx_p‘,vs_msg,SYSDATE);
    COMMIT;
RETURN;
END;

很多其它语法

1 、推断语句:

if 比較式 then begin end; end if;

create or replace procedure test(x in number) is
begin
    if x >0 then
        begin
        x := 0 - x;
        end;
    end if;
    if x = 0 then
        begin
        x: = 1;
        end;
    end if;
end test;

2 、For 循环

For ... in ... LOOP
-- 运行语句
end LOOP;

(1) 循环遍历游标

create or replace procedure test() as
Cursor cursor is select name from student; name varchar(20);
begin
    for name in cursor LOOP
        begin
        dbms_output.putline(name);
        end;
    end LOOP;
end test;

(2) 循环遍历数组

create or replace procedure test(varArray in myPackage.TestArray) as
--( 输入參数varArray 是自己定义的数组类型,定义方式见标题6)
i number;
begin
    i := 1;  -- 存储过程数组是起始位置是从1 開始的,与java 、C 、C++ 等语言不同。由于在Oracle 中本是没有数组的概念的,数组事实上就是一张
    -- 表(Table), 每一个数组元素就是表中的一个记录。所以遍历数组时就相当于从表中的第一条记录開始遍历
    for i in 1..varArray.count LOOP
        dbms_output.putline(‘The No.‘|| i || ‘record in varArray is:‘||varArray(i));
    end LOOP;
end test;

3 、While 循环

while 条件语句 LOOP

begin
end;
end LOOP;

E.g

create or replace procedure test(i in number) as
begin
    while i < 10 LOOP
    begin
    i:= i + 1;
    end;
    end LOOP;
end test;

4 、数组

首先明白一个概念:Oracle 中本是没有数组的概念的。数组事实上就是一张表(Table), 每一个数组元素就是表中的一个记录。

使用数组时,用户能够使用Oracle 已经定义好的数组类型,或可依据自己的须要定义数组类型。

(1) 使用Oracle 自带的数组类型

x array; -- 使用时须要须要进行初始化

e.g:

create or replace procedure test(y out array) is
x array;
begin
    x := new array();
    y := x;
end test;

(2) 自己定义的数组类型 ( 自己定义数据类型时,建议通过创建Package 的方式实现,以便于管理)

create or replace package myPackage is
Public type declarations   type info is record(     name varchar(20),     y number);
type TestArray is table of info index by binary_integer;
-- 此处声明了一个TestArray 的类型数据。事实上其为一张存储Info 数据类型的Table 而已,及TestArray 就是一张表。有两个字段,一个是name ,一个是y 。须要注意的是此处使用了Index by binary_integer 编制该Table 的索引项,也能够不写,直接写成:type TestArray is
table of info ,假设不写的话使用数组时就须要进行初始化:varArray myPackage.TestArray; varArray := new myPackage.TestArray();
end TestArray;

5. 游标的使用 Oracle 中Cursor 是非常实用的,用于遍历暂时表中的查询结果。

其相关方法和属性也非常多,现仅就经常使用的使用方法做一二介绍:

(1)Cursor 型游标( 不能用于參数传递)

create or replace procedure test() is
cusor_1 Cursor is select std_name from student where  ...;  --Cursor 的使用方式1   cursor_2 Cursor;
begin
select class_name into cursor_2 from class where ...;  --Cursor 的使用方式2
可使用For x in cursor LOOP .... end LOOP; 来实现对Cursor 的遍历
end test;

(2)SYS_REFCURSOR 型游标,该游标是Oracle 以预先定义的游标,可作出參数进行传递

create or replace procedure test(rsCursor out SYS_REFCURSOR) is
cursor SYS_REFCURSOR;
name varhcar(20);
begin
OPEN cursor FOR select name from student where ... --SYS_REFCURSOR 仅仅能通过OPEN 方法来打开和赋值
LOOP
fetch cursor into name   --SYS_REFCURSOR 仅仅能通过fetch into 来打开和遍历 exit when cursor%NOTFOUND;              --SYS_REFCURSOR 中可使用三个状态属性:                                         ---%NOTFOUND( 未找到记录信息) %FOUND( 找到记录信息)                                         ---%ROWCOUNT( 然后当前游标所指向的行位置)
dbms_output.putline(name);
end LOOP;
rsCursor := cursor;
end test; 
时间: 2024-08-28 14:32:30

【数据库摘要】12_Sql_存储过程的相关文章

显示数据库中的存储过程__转

It's no easy trick to see stored procedures in a database programmatically with a scripting language like ASP. If you're using MS Access, you're out of luck. Access provides no way to see the actual meat of a stored procedure although you can get the

【数据库摘要】7_Sql_Outer_Join

介绍一个list滑动时通过一个text提示Array首字母位置的应用 /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a

【数据库摘要】10_Sql_Create_Index

CREATE INDEX 语句 CREATE INDEX 语句用于在表中创建索引. 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据. 索引 您可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到索引,它们只能被用来加速搜索/查询. 注释:更新一个包含索引的表需要比更新一个没有索引的表花费更多的时间,这是由于索引本身也需要更新.因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引. SQL CREATE INDEX 语法 在表上创建一个简单的索引.允许使用重复的值

三大数据库下的存储过程实现通用分页

三大数据库下的存储过程实现通用分页  SqlServer数据库下通用存储过程实现分页: 1 --通用存储过程分页 2 CREATE PROCEDURE procList 3 --我们需要传入的参数 4 @strWhere NVARCHAR(max), --查询条件 5 @PageSize INT, --每页显示多少条内容 6 @PageIndex INT , --当前页 7 @TableName NVARCHAR(max), --需要查询的表名 8 @ColName NVARCHAR(max),

java中调用数据库中的存储过程和函数

public static void main(String[] args) {         Connection conn =getConnection(url,user, pwd);         System.out.println("数据连接成功");         CallableStatement cs=null;         try         {    //调用数据库中的存储过程              cs = conn.prepareCall(&q

sql server快速删除整个数据库表和存储过程

情况:在远程数据库删除表执行太慢,表过多,数据库无权删除 结果:保留空数据库 方法:利用sql语句,查询网络文摘解决. 说明: 有些有约束,不能直接delete,需要先删除所有约束,语句: DECLARE c1 cursor for select 'alter table ['+ object_name(parent_obj) + '] drop constraint ['+name+']; ' from sysobjects where xtype = 'F' open c1 declare

数据库索引,存储过程,视图,事务

一,索引索引是一个独立的,物理的数据库结构,可以快速找到表或视图的信息通常情况下只有需要经常查询索引列中的数据时才在表上创建索引基本语法:CREATE INDEX StockIndexON appSchema.StockEvents (StockSymbol);创建唯一索引:Create unique index 索引名称On 表名(字段1,字段2)聚集索引:clustered 每个键值只有一个聚集索引非聚集索引noclustered:索引的键值包含指向表中记录存储位置的指针,不对表中数据排序聚

将当前数据库里所有存储过程的内容进行批量替换方案

将当前数据库里所有存储过程里的内容进行批量替换方案 备份存储过程 USE [MyDB] go IF OBJECT_ID('master..all_proc_before_replace', 'U') IS NOT NULL DROP TABLE master..all_proc_before_replace SELECT o.name AS proc_name, definition , o.type , ' ' AS remark INTO master..all_proc_before_re

mysql导入数据库中的存储过程和函数出现错误的解决办法

mysql导入数据库中的存储过程和函数出现错误的解决办法 调用一个远程拷贝的本地Mysql的储存过程 报错:[Err] 1449 - The user specified as a definer ('repl'@'192.168.1.%') does not exist  解决想法: 凭借以前经常见到的[email protected]报错,给root赋值所有权限: grant all privileges on *.* to [email protected]"%" identif

查询sqlserver数据库视图、存储过程等包含特定的字符串

? 1 2 3 4 5 6 SELECT  A.name ,         B.definition FROM    SYS.objects A         INNER JOIN sys.sql_modules B ON A.object_id = B.object_id                                         AND ( CHARINDEX('包含字符',