oracle 分页存储过程

--创建表
declare num number; 
begin 
select count(1) into num from user_tables where table_name=‘SRCT‘;   --判断当前要创建的表在数据库中是否存在.
if num>0 
then execute immediate ‘drop table ‘||‘SRCT‘; --表名要大写
end if; 
execute immediate ‘CREATE TABLE SRCT
(  
  SN  char(11), 
  XM  varchar2(30),  --姓名 
  KSCJ  number(3),   --考试成绩
  KSRQ  Date         --考试日期
      
)‘; 
end;
/
commit;
/

--注:上面的表名要大写.

--插入数据
declare
maxrecords constant int:=50;
i int:=1;
begin
for i in 1..maxrecords
loop
insert into SRCT(SN,XM,KSCJ,KSRQ)values(i,‘frj‘||i,i+10,sysdate);
end loop
--dbms_output.put_line(‘成功录入数据!‘);
commit;
end;
/
--查询数据,检查数据插入操作是否成功.
SELECT * FROM SRCT WHERE ROWNUM<3;
/

--检查存储过程是否存在
declare 
num number;
msg varchar2(30):= ‘数据库中不存在该存储过程‘;
begin
  select   count(1) into num    
  from   user_objects     
  where   object_type   = ‘PROCEDURE‘   
  and   object_name=‘WRITE_SRC‘  ;
  
  if num>0 
  then 
      msg:= ‘该存储过程已经存在‘;
  end if;
  dbms_output.put_line(msg); 
end ;
/

--创建存储过程
CREATE OR REPLACE Procedure 
WRITE_SRC( M_SN in char  , M_XM in  varchar2,M_KSCJ in integer,
M_KSRQ in Date,RES out integer,ERR out
varchar2)
as
V_COUNT number:=0;
  Begin
  
  RES:=-2;
  ERR:=‘数据库中不存在该纪录,更新失败.‘;
  select count(SN) INTO V_COUNT 
  FROM SRCT 
  Where  SN=M_SN AND XM=M_XM;
  
  IF V_COUNT>0 THEN 
    Update SRCT
    Set KSCJ=M_KSCJ,KSRQ=M_KSRQ
    Where  SN=M_SN AND XM=M_XM;
    Commit;
    RES:=1;
    ERR:=‘更新成功!‘;
   return;
  END IF;
  exception
    when others then
     RES:=-1;
     ERR:=‘更新失败‘;
   return ;
End  ;
/

commit;
/


--调用存储过程
declare 
res int;
err Varchar2(80);
Begin
res:=‘3‘;
err:=‘更新成功‘;
WRITE_SRC(‘1‘,‘frj1‘,300,sysdate,res,err);
COMMIT;
dbms_output.put_line(res);
dbms_output.put_line(err); 
End;
/

select sn,xm,kscj from srct WHERE SN=‘1‘ AND XM=‘frj1‘;
/

--注:易犯错误
--以上语句均在"SQL*Plus 工作单"上运行;

  1.每一个小单元的语句后要加‘;‘号;
  2.不能将字符串赋值的单引号写成双引号;
    如: err:=‘更新成功!‘; 不能写成 err:="更新成功!";
    以上错误系统将提示:"警告: 创建的过程带有编译错误。"
  3.存储过程传递与赋值的参数名称,个数,类型(字段类型,返回的类型(in/out))要与调用的存储过程以及该存储过程
    所访问的表中相应的字段类型严格对应.
    还有一些约定的写法也需遵守.
    如:其中的" M_KSCJ "对应表中的" KSCJ "字段, 应写成(M_KSCJ in integer)不能写成( M_KSCJ in  number(3));
    "M_SN"对应表中的 "SN" 字段,应写成 (M_SN in char) 不能写成 (M_SN in Varchar2)
  4.在c#中进行调用时,还要注意它的输入/输出类型,如上例中的" out integer res "  为输出类型,应将其
      OracleParameter[] parm = new OracleParameter[1];
      parm[0] = new OracleParameter("RES", OracleType.Int16   );
      parm[0].Direction = ParameterDirection.Output  ; --将其设为输出类型;
      具体调用方法将在稍后进行介绍;
  5.定义存储过程时,其参数名称最好不要与字段名称同名(不区分大小写);
     如上面的存储过程建议不要写成:
     WRITE_SRC( SN in char  , XM in  varchar2,KSCJ in integer,
                KSRQ in Date,RES out integer,ERR out varchar2)

//--在c#中的调用
 
 
   public int upInfo(string m_sn,string m_sxm,int m_ikscj,DateTime m_dksrq, out int m_ires, out string m_serr)
        {
            string ConnStr=GetConnStr();
            OracleCommand cmd = new OracleCommand();
            OracleConnection conn = new OracleConnection(ConnStr);
            int rows = 0;
            mres = -110;
            merr = "";
            try
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "WRITE_SRC";
                OracleParameter[] parm = new OracleParameter[6];
                //in
                parm[0] = new OracleParameter("M_SN", OracleType.Char, 11);   --与SQL区别,sql存储过程需要在定义与此处,在其参数前加"@"符号;
                parm[1] = new OracleParameter("M_XM", OracleType.VarChar, 2);
                parm[2] = new OracleParameter("M_KSCJ", OracleType.Number, 3);
                parm[3] = new OracleParameter("M_KSRQ", OracleType.DateTime , 8);
                //out
                parm[4] = new OracleParameter("RES", OracleType.Int16);
                parm[5] = new OracleParameter("ERR", OracleType.VarChar, 50);

                //指明参数是输入还是输出型
                for (int i = 0; i < parm.Length-2; i++)
                {
                    parm[i].Direction = ParameterDirection.Input;
                }
                parm[4].Direction = ParameterDirection.Output;
                parm[5].Direction = ParameterDirection.Output;

              
                //给参数赋值
                parm[0].Value = m_sn;
                parm[1].Value = m_sxm;
                parm[2].Value = m_ikscj;
                parm[3].Value = OracleDateTime.Parse(m_dksrq.ToShortDateString());
                --直接用update语句更新时,需要采用下面的日期格式.
                -- string msksrq = mksrq.Day.ToString() + "-" + mksrq.Month.ToString() + "月" + " -" + mksrq.Year.ToString().Substring(2, 2);
          
                //传递参数给Oracle命令
                for (int i = 0; i < parm.Length; i++)
                {
                    cmd.Parameters.Add(parm[i]);
                }

                //打开连接
                if (conn.State != ConnectionState.Open)
                    conn.Open();

                cmd.Connection = conn;
                rows = cmd.ExecuteNonQuery();

                //取出返回值
                m_ires = Convert.ToInt16(parm[4].Value);//res
                m_serr = parm[5].Value.ToString();//err

            }
            catch (Exception er)
            {
                merr = System.Environment.NewLine + "res:" + m_ires.ToString() + "err:" + er.ToString();
                MrfuWriteEventLog.C_WriterEventLog.WriteEventLogAppend("UploadDriInfo: mres=" + m_ires.ToString() + "merr:" + er.ToString());
            }
            finally
            {
                //关闭连接,释放空间.
                if (conn.State == ConnectionState.Open)
                    conn.Close();
                conn.Dispose();
                cmd.Parameters.Clear();
                cmd.Dispose();
            }

            return rows;
        }

--按时间段分页显示
 
select sn,xm,kscj,ksrq from SRCT  
where ksrq between  to_date(‘2003-01-01‘,‘yyyy-mm-dd‘)   and   to_date(‘2007-06-28‘,‘yyyy-mm-dd‘) order by ksrq;
/


select * from 
( select b.*,rownum row_num from
    (
     select  sn,xm,kscj,ksrq from SRCT  c
     where ksrq between  to_date(‘2003-01-01‘,‘yyyy-mm-dd‘)   and   to_date(‘2007-06-28‘,‘yyyy-mm-dd‘) order by c.sn 
     )b
)a where a.row_num between 1 and 10; 

/
--注: oracle的rownum是在提取记录时就已经生成,它先于排序操作,所以必须使用子查询先排序.

--==转oracle分页存储过程==
CREATE OR REPLACE  PACKAGE DotNet  is

  TYPE type_cur IS REF CURSOR;     --定义游标变量用于返回记录集
  PROCEDURE DotNetPagination
  (
  Pindex in number,                --分页索引
  Psql in varchar2,                --产生dataset的sql语句
  Psize in number,                 --页面大小
  Pcount out number,               --返回分页总数
  v_cur out type_cur               --返回当前页数据记录
  );
  procedure DotNetPageRecordsCount
  (
  Psqlcount in varchar2,           --产生dataset的sql语句
  Prcount   out number             --返回记录总数
  );
end DotNet;
/
CREATE OR REPLACE  PACKAGE BODY DotNet  is
 --***************************************************************************************
  PROCEDURE DotNetPagination
  (
  Pindex in number,
  Psql in varchar2,
  Psize in number,
  Pcount out number,
  v_cur out type_cur
  )
  AS
  v_sql VARCHAR2(1000);
  v_count number;
  v_Plow number;
  v_Phei number;
  Begin
  ------------------------------------------------------------取分页总数
  v_sql := ‘select count(*) from (‘ || Psql || ‘)‘;
  execute immediate v_sql into v_count;
  Pcount := ceil(v_count/Psize);
  ------------------------------------------------------------显示任意页内容
  v_Phei := Pindex * Psize + Psize;
  v_Plow := v_Phei - Psize + 1;
  --Psql := ‘select rownum rn,t.* from cd_ssxl t‘ ;            --要求必须包含rownum字段
  v_sql := ‘select * from (‘ || Psql || ‘) where rn between ‘ || v_Plow || ‘ and ‘ || v_Phei ;
  open v_cur for v_sql;
  End DotNetPagination;
 --**************************************************************************************
  procedure DotNetPageRecordsCount
  (
  Psqlcount in varchar2,
  Prcount   out number
  )
  as
  v_sql varchar2(1000);
  v_prcount number;
  begin
  v_sql := ‘select count(*) from (‘ || Psqlcount || ‘)‘;
  execute immediate v_sql into v_prcount;
  Prcount := v_prcount;                  --返回记录总数
  end DotNetPageRecordsCount;
 --**************************************************************************************
end DotNet;

/

//==使用示例==
       /**//// <summary>
       /// 填充dataSet数据集-Oracle库
       /// </summary>
       /// <param name="pindex">当前页</param>
       /// <param name="psql">执行查询的SQL语句</param>
       /// <param name="psize">每页显示的记录数</param>
       /// <returns></returns>
      private bool gridbind(int pindex, string psql, int psize)
     {
            OracleConnection conn = new OracleConnection();
            OracleCommand cmd = new OracleCommand();
            OracleDataAdapter dr = new OracleDataAdapter();
            conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            cmd.Connection = conn;
            cmd.CommandType = CommandType.StoredProcedure;
            conn.Open();
            cmd.CommandText = "DotNet.DotNetPageRecordsCount";
            cmd.Parameters.Add("psqlcount", OracleType.VarChar).Value = psql;
            cmd.Parameters.Add("prcount", OracleType.Number).Direction = ParameterDirection.Output;
            
            cmd.ExecuteNonQuery();
            string PCount = cmd.Parameters["prcount"].Value.ToString();
            cmd.Parameters.Clear();
            cmd.CommandText = "DotNet.DotNetPagination";
            if (pindex != 0)
            {
                cmd.Parameters.Add("pindex", OracleType.Number).Value = pindex - 1;
            }
            else
            {
                cmd.Parameters.Add("pindex", OracleType.Number).Value = pindex;
            }
            cmd.Parameters.Add("psql", OracleType.VarChar).Value = psql;
            cmd.Parameters.Add("psize", OracleType.Number).Value = psize;
            cmd.Parameters.Add("v_cur", OracleType.Cursor).Direction = ParameterDirection.Output;
            cmd.Parameters.Add("pcount", OracleType.Number).Direction = ParameterDirection.Output;
            dr.SelectCommand = cmd;
            try
            {
                ds = new DataSet();
                dr.Fill(ds);
                //显示页码条的状态
                showStatus(Convert.ToInt32(cmd.Parameters["pindex"].Value) + 1,
                    Convert.ToInt32(cmd.Parameters["pcount"].Value),
                    Convert.ToInt32(PCount));
                for (int i = 0; i < ds.Tables.Count; i++)
                { //把数据行为零的表删除
                    if (ds.Tables[i].Rows.Count == 0)
                        ds.Tables.Remove(ds.Tables[i].TableName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
 
            conn.Close();
            return true;
    }

时间: 2024-10-05 20:52:52

oracle 分页存储过程的相关文章

oracle分页存储过程

oracle分页存储过程: CREATE OR REPLACE PROCEDURE FGK.prc_page (p_tableName in varchar2, --表名 p_strWhere in varchar2, --查询条件 p_orderColumn in varchar2, --排序的列 p_orderStyle in varchar2, --排序方式 p_curPage in out Number, --当前页 p_pageSize in out Number, --每页显示记录条

java调用Oracle分页存储过程

Java程序 package com.test; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import com.jdbc.BaseJdbcDAO; import oracle.jdbc.OracleTypes; public class Test { /

我的oracle分页存储过程

create or replace package TX_PKG_PAGEPACKAGE is type TX_RESULTLIST is ref cursor; procedure TX_PRC_PAGINATION(tx_resultlist out TX_RESULTLIST,insql in varchar2,currentpage in number,pagecount in number); end; create or replace package body TX_PKG_PAG

Oracle实践--PL/SQL综合之分页存储过程

当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说StringBuilder中,有这么一句,"将StringBuilder 的实例用于多个线程是不安全的.如果需要这样的同步,则建议使用StringBuffer. ",那么下面手动创建一个线程不安全的类,然后在多线程中使用这个类,看看有什么效果. Count.java: [java] view plaincopy public class Count { private int num; public 

Oracle利用存储过程性 实现分页

分页的简单配置 在上一次已经说过了 这边说说怎么在存储过程中实现分页 首先建立存储过程 参考 http://www.cnblogs.com/gisdream/archive/2011/11/16/2251687.html 基本的代码如下所示 1.在oracle的sqlplus或其他工具中运行一下pl/sql块建立存储过程 ------------------------------------------------------------ --分页存储过程 ------------------

[转]Oracle分页之二:自定义web分页控件的封装

本文转自:http://www.cnblogs.com/scy251147/archive/2011/04/16/2018326.html 上节中,讲述的就是Oracle存储过程分页的使用方式,但是如果大量的页面要使用这个分页存储过程,如果利用上节的方式,势必要书写大量的代码.如何才能够少些代码书写量呢?当然了,利用自定义web控件进行一下封装,也许是一个好方法,但是如何进行封装呢? 首先,就是在项目中添加一个“Web 用户控件“的页面,我们定义为:MyPagination.ascx 然后,就是

【老码农怀旧】一个简单好用的分页存储过程

数据库存储过程是一组预先创建并用指定的名称存储在数据库服务器上的 SQL 语句,将使用比较频繁或者比较复杂的操作,预先用 SQL 语句写好并用一个指定的名称存储起来,以后当需要数据库提供与已定义好的存储过程的功能相同的服务时,只需再次执行该存储过程. 数据库存储过程的优点: (1)存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以大大提高数据库执行速度. (2)通常,复杂的业务逻辑需要多条 SQL 语句.这些语句要分别

SQL基础分页存储过程(案例一)

1 --分页 存储过程 案例 2 3 -- 所执行的存储过程 4 create proc pageForUsers 5 @currPage int, --当前页数 6 @pageSize int, --每页多少条记录 7 @count int output --总记录数 8 as 9 declare @firstIndex int 10 declare @lastIndex int 11 declare @sqlText varchar(200) 12 13 --统计总记录数 14 select

多表查询分页存储过程,解决了第二页不显示的问题

SET ANSI_NULLS OFFGOSET QUOTED_IDENTIFIER OFFGO ALTER PROCEDURE [dbo].[UP_Pagination]/****************************************************************** 千万数量级分页存储过程 *****************************************************************参数说明:1.Tables :表名称,视