用Silverlight提供分页特性参考http://hi.baidu.com/mldark/blog/item/cbbdc3c30ffe5f21e4dd3bc4.html这个文章
接下来讲解用服务端分页合适上万数据使用
首先在数据库创建一个表 随便取名
然后创建一个存储过程 取名DataGridPages
CreatePROCEDURE [dbo].[DataGridPages] (@pageindex int,@pagesize int )ASBEGIN with pages as ( SELECT id,text,ROW_NUMBER()over(order by id)as pageindex FROM dbo.t1 ) SELECT * FROM pages where pageindex between(@pageindex*@pagesize)+1 and (@pageindex+1)*@pagesize
END
我用的是sqlserver2008版本 创建好了 然后在wcf创建类型
cs代码
namespace WcfService1{ // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 [ServiceContract] public interface IService1 {
[OperationContract] List
// TODO: 在此添加您的服务操作 }
// 使用下面示例中说明的数据协定将复合类型添加到服务操作 [DataContract] public class CData { [DataMember] public int id; [DataMember] public string text;
}
[System.ServiceModel.Activation.AspNetCompatibilityRequirements(RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Required)] public class Service1 : IService1 {
public List
}
public int PageCount(int pagesize) { SqlConnection cn = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["sldatabaseConnectionString"].ConnectionString); SqlCommand cmd=new SqlCommand ("SELECT COUNT(id) FROM t1" ,cn); cn.Open(); int count =int.Parse( cmd.ExecuteScalar().ToString()); cn.Close();
if (count % pagesize == 0)//如果有余数的话+1 return count / pagesize; else return count / pagesize + 1; } }
在xaml代码
using System;using System.Collections.Generic;using System.Linq;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using SilverlightApplication1.ServiceReference1;
namespace SilverlightApplication1{ public partial class DataGridControl : UserControl { int currentIndex = 0;//当前素引 int pagesize = 5;//每页项数 int pagecount;//页总数 SilverlightApplication1.ServiceReference1.Service1Client c = new ServiceReference1.Service1Client(); public DataGridControl() { InitializeComponent(); c.GetCDatasCompleted += new EventHandler
void c_PageCountCompleted(object sender, PageCountCompletedEventArgs e) { if (e.Error == null) { pagecount = e.Result; textBlock1.Text = currentIndex + 1 + "/" + pagecount; } }
void c_GetCDatasCompleted(object sender, ServiceReference1.GetCDatasCompletedEventArgs e) { if (e.Error == null) { dataGrid1.ItemsSource = e.Result;
}
}
private void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e) { }
//下页 private void button2_Click(object sender, RoutedEventArgs e) { currentIndex++; if (pagecount-1 <= currentIndex) { currentIndex = pagesize -3; c.GetCDatasAsync(currentIndex, pagesize); button2.IsEnabled = false; button1.IsEnabled = true; } else { c.GetCDatasAsync(currentIndex, pagesize); button1.IsEnabled = true; } textBlock1.Text = currentIndex+1 + "/" + pagecount; } //上页 private void button1_Click(object sender, RoutedEventArgs e) { currentIndex--; if (0 >= currentIndex) { currentIndex = 0; c.GetCDatasAsync(currentIndex, pagesize); button1.IsEnabled = false; button2.IsEnabled = true; } else { c.GetCDatasAsync(currentIndex, pagesize); button2.IsEnabled = true; } textBlock1.Text = currentIndex + 1 + "/" + pagecount; } }}
∙
∙ |
∙ 浏览:338
∙ |
∙ 更新:2013-10-23 15:45
Oracle创建存储过程
∙ pl/sql
1. 第一步:找到procedures,右键新建
2. 第二步:在name中输入存储过程名字(这里输入的就是你以后需要调用的名字),parameters后是参数,在里面定义参数的类型。
3. 第三步:编写存储过程语句。
4. 第四步: 存储过程调用
CallableStatement cs=conn.divpareCall("{call mymd_gis_pro(?,?,?,?,?)}"); //1代表第一个参数,setint表示参数类型是int型 cs.setInt(1,188);
cs.setInt(2,12); cs.setInt(3,12);
...... //执行Oracle存储过程 cs.execute();
随笔- 244 文章- 8 评论- 106
1 由于交叉表的八个报表写在sql中了,每个报表对应sql语句有300行之多,不能定义视图,因为必须传递个参数,所以利用了存储过程实现。
首先,定义包,然后定义包体,在用.net调用生成数据集即可
.net调用oracle带参数的存储过程,返回数据集
Oracle这个复杂一些,步骤如下:
在pl/sql中首先写包的定义文件
CREATE OR REPLACE PACKAGE ZHBB AS TYPE t_cursor IS REF CURSOR ;Procedure ZH11 (rq IN char, io_cursor IN OUT t_cursor);
Procedure ZH12 (rq IN char, io_cursor IN OUT t_cursor);
END ZHBB;
其次写包体的定义文件
CREATE OR REPLACE PACKAGE BODY ZHBB AS
Procedure ZH11(rq IN char, io_cursor IN OUT t_cursor) IS
v_cursor t_cursor;
BEGIN
OPEN v_cursor FOR
Select * from aa where ny=rq;
io_cursor := v_cursor;
END ZH11;
Procedure ZH12 (rq IN char, io_cursor IN OUT t_cursor) IS
。。。。。
END ZH12;
.net调用方法:
public static DataTable GetDataTable(string PackageName,string ProName,string connString,string rq)
{
connString=” Provider= MSDAORA.1;User ID=xx;Data Source=xx;Password=xx;”
//定义下新的链接方法,因为原来的驱动"OraOLEDB.Oracle"不能满足需求,设置为"MSDAORA.1"
OleDbConnection Oraclecon = new OleDbConnection(connString);
Oraclecon.Open();
OleDbCommand cmd = new OleDbCommand("{Call "+ PackageName +"."+ ProName +"(?, {resultset 0, io_cursor} )}", Oraclecon);
cmd.Connection = Oraclecon;
cmd.Parameters.Add("rq", OleDbType.VarChar, 8).Value = ""+ rq +"";
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
//DataSet ds = new DataSet();
da.Fill(dt);
Oraclecon.Close();
Oraclecon.Dispose();
return dt;
}
}
ASP.NET调用oracle存储过程实现快速分页的步骤如下:Oracle 9i 包定义:
create or replace package MaterialManage isTYPE T_CURSOR IS REF CURSOR;Procedure Per_QuickPage(TbName in varchar2, --表名FieldStr in varchar2, --字段集RowFilter in varchar2, --过滤条件SortStr in varchar2, --排序集RownumFieldStr in varchar2, --分页条件TotalCount out number, --总记录数Cur_ReturnCur out T_CURSOR --返回的游标);end MaterialManage;
Oracle 9i 包主体:
create or replace package body MaterialManage isProcedure Per_QuickPage(TbName in varchar2, --表 名FieldStr in varchar2, --字段集RowFilter in varchar2, --过滤条件SortStr in varchar2, --排序集MinRowNum in number, --分页小值MaxRowNum in number, --分页大值TotalCount out number, --总记录数Cur_ReturnCur out T_CURSOR)isv_SourceTb1 varchar2(3000); --动态表名1v_SourceTb2 varchar2(3000); --动态表名2v_SourceTb3 varchar2(3000); --动态表名3v_SourceTb4 varchar2(3000); --动态表名4v_TotalCount varchar2(50); --总记录数v_sql varchar2(3000); --动态sql beginv_SourceTb1 := ''(select ''|| FieldStr ||'' from ''|| TbName ||'') SourceTb1'';v_SourceTb2 := ''(select * from ''|| v_SourceTb1 ||'' where ''|| RowFilter ||'' ''|| SortStr ||'') SourceTb2'';v_SourceTb3 := ''(select rownum as Rowindex,SourceTb2.* from ''|| v_SourceTb2 ||'' where rownum<=''|| MaxRowNum ||'') SourceTb3'';v_SourceTb4 := ''(select * from ''|| v_SourceTb1 ||'' where ''|| RowFilter ||'') SourceTb4'';v_sql := ''select count(*) as TotalCount from ''|| v_SourceTb4;execute immediate v_sql into v_TotalCount;TotalCount := v_TotalCount;v_sql := ''select * from ''|| v_SourceTb3 ||'' where RowIndex >=''||MinRowNum;open Cur_ReturnCur for v_sql;end Per_QuickPage;END MaterialManage;
由于oracle有个rownum特性,所以分页的时候就是利用rownum来实现。如果大家还有什么更好的办法记得告诉我一声,多谢了,因为我测试了上面的分页方法效率并不是很高。
存储过程返回了两个参数:TotalCount :当前条件下的总记录数 Cur_ReturnCur :游标类型,就是所要读取的记录的集合
下面是ASP.NET中调用的代码:
///
在oracle的存储过程中返回记录集,需要用到游标变量,oracle不能像sqlserver那样可以直接返回一个记录集。由于设想在.net中把复杂的sql语句生成,所以在存储过程中没有去考虑生成sql语句的问题。--------------------------------------------------------------------------------------------------------------------------------------以下是在oracle中实现的分页存储过程。create or replace package DotNet is -- Author : good_hy -- Created : 2004-12-13 13:30:30 -- Purpose : 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 DotNot;--------------------------------------------------------------------------------------------------------------------------------------------------------------------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 DotNot;------------------------------------------------------------------------------------------------------------------------------------------------------------------------以下是在.net中调用oracle分页存储过程的步骤。(vb.net)在.net调用返回记录集的存储过程,需要用到datareader,但是datareader不支持在datagrid中的分页,因此需要利用datagrid自定义分页功能。 Protected WithEvents DataGrid1 As System.Web.UI.WebControls.DataGrid Dim conn As New OracleClient.OracleConnection() Dim cmd As New OracleClient.OracleCommand() Dim dr As OracleClient.OracleDataReaderPrivate Sub gridbind(ByVal pindex As Integer, ByVal psql As String, Optional ByVal psize As Integer = 10) conn.ConnectionString = "Password=gzdlgis;User ID=gzdlgis;Data Source=gzgis" cmd.Connection = conn cmd.CommandType = CommandType.StoredProcedure conn.Open() '------------------------------------------------------------------------------------ cmd.CommandText = "DotNot.DotNetPageRecordsCount" '------------------------------------------------------------------------------------ cmd.Parameters.Add("psqlcount", OracleType.VarChar).Value = psql cmd.Parameters.Add("prcount", OracleType.Number).Direction = ParameterDirection.Output cmd.ExecuteNonQuery() Me.DataGrid1.AllowPaging = True Me.DataGrid1.AllowCustomPaging = True Me.DataGrid1.PageSize = psize Me.DataGrid1.VirtualItemCount = cmd.Parameters("prcount").Value cmd.Parameters.Clear() '------------------------------------------------------------------------------------ cmd.CommandText = "DotNot.DotNetPagination" '------------------------------------------------------------------------------------ cmd.Parameters.Add("pindex", Data.OracleClient.OracleType.Number).Value = pindex cmd.Parameters.Add("psql", Data.OracleClient.OracleType.VarChar).Value = psql '"select rownum rn,t.* from cd_ssxl t" cmd.Parameters.Add("psize", Data.OracleClient.OracleType.Number).Value = psize cmd.Parameters.Add("v_cur", Data.OracleClient.OracleType.Cursor).Direction = ParameterDirection.Output cmd.Parameters.Add("pcount", Data.OracleClient.OracleType.Number).Direction = ParameterDirection.Output dr = cmd.ExecuteReader() Me.DataGrid1.DataSource = dr Me.DataGrid1.DataBind() dr.Close() conn.Close() Response.Write("总计页数 " & cmd.Parameters("pcount").Value) End Sub---------------------------------------------------------------------------------------------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not Page.IsPostBack Then Dim psql As String = "select rownum rn,t.* from cd_ssxl t" gridbind(0, psql, 20) End If End Sub Private Sub DataGrid1_PageIndexChanged(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridPageChangedEventArgs) Handles DataGrid1.PageIndexChanged Dim psql As String = "select rownum rn,t.* from cd_ssxl t" Me.DataGrid1.CurrentPageIndex = e.NewPageIndex gridbind(e.NewPageIndex, psql, 20) End Sub
4。访问 Oracle 过程/函数(1)
SQL Server 作程序时经常使用存储过程,Oracle 里也可以使用过程,还可以使用函数。Oracle 的过程似乎是不能有返回值的,有返回值的就是函数了(这点有些像 BASIC,函数/过程区分的很细致。SQL Server 存储过程是可以有返回值的)。
.NET 访问 Oracle 过程/函数的方法很类似于 SQL Server,例如:
OracleParameter[] parameters = { new OracleParameter("ReturnValue", OracleType.Int32, 0, ParameterDirection.ReturnValue, true, 0, 0, "", DataRowVersion.Default, Convert.DBNull ) new OracleParameter("参数1", OracleType.NVarChar, 10), new OracleParameter("参数2", OracleType.DateTime), new OracleParameter("参数3", OracleType.Number, 1) };parameters[1].Value = "test";parameters[2].Value = DateTime.Now;parameters[3].Value = 1; // 也可以是 new OracleNumber(1);
OracleConnection connection = new OracleConnection( ConnectionString );OracleCommand command = new OracleCommand("函数/程名", connection);command.CommandType = CommandType.StoredProcedure;foreach(OracleParameter parameter in parameters) command.Parameters.Add( parameter );connection.Open();command.ExecuteNonQuery();int returnValue = parameters[0].Value; //接收函数返回值connection.Close();
Parameter 的 DbType 设定请参见 System.Data.OracleClient.OracleType 枚举的文档,比如:Oracle 数据库中 Number 类型的参数的值可以用 .NET decimal 或 System.Data.OracleClient.OracleNumber 类型指定; Integer 类型的参数的值可以用 .NET int 或 OracleNumber 类型指定。等等。
上面例子中已经看到函数返回值是用名为“ReturnValue”的参数指定的,该参数为 ParameterDirection.ReturnValue 的参数。
5。访问 Oracle 过程/函数 (2)
不返回记录集(没有 SELECT 输出)的过程/函数,调用起来和 SQL Server 较为类似。但如果想通过过程/函数返回记录集,在 Oracle 中就比较麻烦一些了。
在 SQL Server 中,如下的存储过程:
CREATE PROCEDURE GetCategoryBooks( @CategoryID int)ASSELECT * FROM BooksWHERE CategoryID = @CategoryIDGO
在 Oracle 中,请按以下步骤操作:
(1)创建一个包,含有一个游标类型:(一个数据库中只需作一次)
CREATE OR REPLACE PACKAGE Test AS TYPE Test_CURSOR IS REF CURSOR;END Test;
(2)过程:
CREATE OR REPLACE PROCEDURE GetCategoryBooks( p_CURSOR out Test.Test_CURSOR, -- 这里是上面包中的类型,输出参数 p_CatogoryID INTEGER)ASBEGIN OPEN p_CURSOR FOR SELECT * FROM Books WHERE CategoryID=p_CatogoryID;END GetCategoryBooks;
(3).NET 程序中:
OracleParameters parameters = { new OracleParameter("p_CURSOR", OracleType.CURSOR, 2000, ParameterDirection.Output, true, 0, 0, "", DataRowVersion.Default, Convert.DBNull), new OracleParameter("p_CatogoryID", OracleType.Int32)};parameters[1].Value = 22;OracleConnection connection = new OracleConnection( ConnectionString );OracleCommand command = new OracleCommand("GetCategoryBooks", connection);command.CommandType = CommandType.StoredProcedure;foreach(OracleParameter parameter in parameters) command.Parameters.Add( parameter );connection.Open();OracleDataReader dr = command.ExecuteReader();while(dr.Read()){ // 你的具体操作。这个就不需要我教吧?}connection.Close();
另外有一点需要指出的是,如果使用 DataReader 取得了一个记录集,那么在 DataReader 关闭之前,程序无法访问输出参数和返回值的数据。
好了,先这些,总之 .NET 访问 Oracle 还是有很多地方和 SQL Server 不同的,慢慢学习了。
在我的上一个银行项目中,我接到编写ORACLE存储过程的任务,我是程序员,脑袋里只有一些如何使用CALLABLE接口调用存储过程的经验,一时不知如何下手,我查阅了一些资料,通过实践发现编写ORACLE存储过程是非常不容易的工作,即使上路以后,调试和验证非常麻烦。简单地讲,Oracle存储过程就是存储在Oracle数据库中的一个程序。
一. 概述
Oracle存储过程开发的要点是:
? 使用Notepad文本编辑器,用Oracle PL/SQL编程语言写一个存储过程;
? 在Oracle数据库中创建一个存储过程;
? 在Oracle数据库中使用SQL*Plus工具运行存储过程;
? 在Oracle数据库中修改存储过程;
? 通过编译错误调试存储过程;
? 删除存储过程;
二.环境配置
包括以下内容:
? 一个文本编辑器Notepad;
? Oracle SQL*Plus工具,提交Oracle SQL和PL/SQL 语句到Oracle database。
? Oracle 10g express数据库,它是免费使用的版本;
需要的技巧:
? SQL基础知识,包括插入、修改、删除等
? 使用Oracle's SQL*Plus工具的基本技巧;
? 使用Oracle's PL/SQL 编程语言的基本技巧;
三.写一个存储过程
存储过程使用Oracle's PL/SQL 程序语言编写,让我们写一个什么工作都不做的存储过程,我们可以编译和运行它而不用担心会对数据库产生任何损害。
在Notepad, 写下:
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
NULL;
END;
把文件存为skeleton.sql.
让我们一行行遍历这个存储过程:
1 CREATE OR REPLACE PROCEDURE skeleton
2 IS
3 BEGIN
4 NULL;
5 END;
行1:
CREATE OR REPLACE PROCEDURE 是一个SQL语句通知Oracle数据库去创建一个叫做skeleton存储过程, 如果存在就覆盖它;
行2:
IS关键词表明后面将跟随一个PL/SQL体。
行3:
BEGIN关键词表明PL/SQL体的开始。
行4:
NULL PL/SQL语句表明什么事都不做,这句不能删去,因为PL/SQL体中至少需要有一句;
行5:
END关键词表明PL/SQL体的结束
四.创建一个存储过程
SQL语句CREATE OR REPLACE PROCEDURE在Oracle数据库中创建、编译和保存一个存储过程。
从Window打开SQL*Plus并且从SQL*Plus登录到你的数据库;打开skeleton.sql文件.
在SQL>命令提示符下输入以下命令:
SQL>@skeleton
SQL>/
SQL*Plus装载skeleton.sql文件的内容到SQL*Plus缓冲区并且执行SQL*Plus语句;SQL*Plus 会通知你存储过程已经被成功地创建。
现在你的存储过程被创建,编译和保存在你的Oracle数据库,我们可以运行它。
五.运行一个存储过程
从SQL*Plus 命令行提示符运行你的存储过程使用EXECUTE命令,如下:
SQL> EXECUTE skeleton;
SQL*Plus 输出一下信息确信存储过程成功执行: PL/SQL procedure successfully completed.
你也可以在一个无名PL/SQL块内运行你的存储过程,在SQL*Plus命令提示符下,它看起来像:
SQL> BEGIN
2 SKELETON;
3 END;
4 /
现在我们已经运行了我们的存储过程,我们如何修改它呢?
六.修改一个存储过程
让我们写一个输出字符串“Hello World!”的存储过程,用Notepad打开你的skeleton.sql 文件,. 用DBMS_OUTPUT.PUT_LINE 过程调用去替换NULL语句,如下所示:
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello World!');
END;
保存到文件skeleton.sql.
从SQL*Plus命令行, 打开文件skeleton.sql .
SQL> @skeleton
SQL>
1 CREATE OR REPLACE PROCEDURE skeleton
2 IS
3 BEGIN
4 DBMS_OUTPUT.PUT_LINE('Hello World!');
5* END;
SQL> /
SQL*Plus 通知你存储过程成功创建并输出提示信息:Procedure created.
SQL>
用EXECUTE 命令运行你的存储过程:
SQL> EXECUTE skeleton;
SQL*Plus显示存储过程运行成功:PL/SQL procedure successfully completed.
我们想要的输出字符串 "Hello World!"没有出来,在显示一个DBMS_OUTPUT.PUT_LINE 结果前需要运行一个SET命令,在SQL*Plus 命令行提示符,键入:
SQL> SET SERVEROUTPUT ON
再次执行你的存储过程:
SQL> EXECUTE skeleton;
现在结果输出了:Hello World!
PL/SQL procedure successfully completed.
七.调试一个存储过程
当调试一个存储过程时,遵循一样的步骤,修改SQL文件,创建存储过程,执行存储过程,根据编译器反馈的出错信息进行修改,这一步是非常繁琐的,需要依靠经验。
在实际的商用存储过程的开发调试过程中,由于涉及很多表、类型、光标、循环、条件等复杂的逻辑,和PL/SQL语句的灵活运用,编译时会产生很多错误提示信息,程序员在根据这些错误信息定位,进行修正,再编译最后得到正确的结构;
八.放弃一个存储过程
如果在数据库中你不在需要一个存储过程你可以删除它,SQL语句 DROP PROCEDURE 完成从数据库中删除一个存储过程,DROP PROCEDURE 在SQL中被归类为数据定义语言(DDL) 类操作,其他的例子有CREATE, ALTER, RENAME 和TRUNCATE。.
在SQL*Plus 命令提示符下,使用DROP PROCEDURE SQL 语句删除你的叫做skeleton的存储过程:
SQL> DROP PROCEDURE skeleton;
SQL*Plus assures us the procedure has been removed:
Procedure dropped.
总结
本文详细讨论了如何使用Oracle工具开发Oracle商用存储过程的步骤。最后在存储过程的使用中可能是程序直接调用,也可能被触发器调用。
¥29.8
¥9.9
¥59.8