存储过程

一、相比于在程序当中写sql语句的数据库开发方式,存储过程是有很多优势的,其中最突出的两点:

1、将程序的与数据库从架构上面相互分离,但需求变化的时候,比如说原来查询字段a,但是后来突然改变要去查询字段ab--我们直接改写存储过程就可以了,不需要去改变程序。

2、存储过程会在数据库做缓存,就是说在客户端访问一次过后,请求查询的结果会被缓存下来,对于大并发量的产品是有很多好处的

二、下面我以.net例子编写简单的存储过程的例子:

1. 只返回单一记录集的存储过程

新建一个网站

存储过程

 

把配置文件Web.config改写如下

<connectionStrings>

<add name="TestConnectionString" connectionString="Data Source=127.0.0.1;Initial Catalog=TestDemo;Persist Security Info=True;User ID=sa;Password=qs@123456" providerName="System.Data.SqlClient"/>

</connectionStrings>

在数据库下建一个表:CategoriesphoneModelphoneTest

存储过程

 

存一些值

 

存储过程

 

创建存储过程:

 

这是通过sql语句去创建
CREATE PROCEDURE Categoriestest1 

 

AS

 

select * 

 

from  Categories

 

GO

 

之后我们可以看到如下的存储过程

 

存储过程

 

Default.aspx页面下面,

 

加入如下控件
 <asp:GridView ID="GridView1" runat="server">

 

        </asp:GridView>

 

在Default.aspx.cs

 

添加入下代码:

 

protected void Page_Load(object sender, EventArgs e)

 

{

 

   fillGridView();

 

}

 

 

 

public void fillGridView() {

 

SqlConnection sqlconn = new SqlConnection(conn);

 

     SqlCommand cmd = new SqlCommand();

 

     // 设置sql连接

 

     cmd.Connection = sqlconn;

 

     // 如果执行语句

 

     cmd.CommandText = "Categoriestest1";

 

     // 指定执行语句为存储过程

 

    cmd.CommandType = CommandType.StoredProcedure;

 

  SqlDataAdapter dp = new SqlDataAdapter(cmd);

 

DataSet ds = new DataSet();

 

    // 填充dataset

 

dp.Fill(ds);

 

// 以下是显示效果

 

GridView1.DataSource = ds;

 

GridView1.DataBind();    

 

}

 

跑一下,得到如下的结果

 

存储过程

 

2. 没有输入输出的存储过程

 

改上例中的表结构为

存储过程

建立如下的存储过程

CREATE PROCEDURE Categoriestest2  AS

insert into dbo.Categories 

(CategoryName,Description,Picture)

values ('test1','test1',null)

GO

 

在Default.aspx页面中,拖入控件

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

在Default.aspx.cs文件中添加如下的代码:

protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

        SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

 

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest2";

        cmd.CommandType = CommandType.StoredProcedure;

        sqlconn.Open();

        // 执′行D并¢显?示?影?响ì行D数簓

        Label1.Text = cmd.ExecuteNonQuery().ToString();

        sqlconn.Close();

    }

 

3. 有返回值的存储过程

 

 

 

存储过程:

CREATE PROCEDURE Categoriestest3
AS
insert into dbo.Categories 
(CategoryName,[Description],[Picture])
values ('test1','test1',null)
return @@rowcount
GO

 

C#代码:

 protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

       

SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest3";

        cmd.CommandType = CommandType.StoredProcedure;

        // 创建参数

        IDataParameter[] parameters = {

                new SqlParameter("rval", SqlDbType.Int,4)

            };

        // 将参数类型设置为 返回值类型

        parameters[0].Direction = ParameterDirection.ReturnValue;

        // 添加参数

        cmd.Parameters.Add(parameters[0]);

 

        sqlconn.Open();

        // 执行存储过程并返回影响的行数

        Label1.Text = cmd.ExecuteNonQuery().ToString();

        sqlconn.Close();

        // 显示影响的行数和返回值

        Label1.Text += "-" + parameters[0].Value.ToString() ;}

 

4. 有输入参数和输出参数的存储过程

表:

 

存储过程:

CREATE PROCEDURE Categoriestest4

@id int output,

@CategoryName nvarchar(15)

AS

insert into dbo.Categories 

(CategoryName,Description,Picture)

values (@CategoryName,'test1',null)

set  @id = @@IDENTITY

GO

 

C#代码:

 protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

        string conn = ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;

        SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest4";

        cmd.CommandType = CommandType.StoredProcedure;

        // 创建参数

        IDataParameter[] parameters = {

                new SqlParameter("@Id", SqlDbType.Int,4) ,

                new SqlParameter("@CategoryName", SqlDbType.NVarChar,15) ,

            };

        // 设置参数类型

        parameters[0].Direction = ParameterDirection.Output;  // 设置为输出参数

        parameters[1].Value = "testCategoryName";

        // 添加参数

        cmd.Parameters.Add(parameters[0]);

        cmd.Parameters.Add(parameters[1]);

 

        sqlconn.Open();

        // 执行存储过程并返回影响的行数

        Label1.Text = cmd.ExecuteNonQuery().ToString();

        sqlconn.Close();

        // 显示影响的行数和输出参数

        Label1.Text += "-" + parameters[0].Value.ToString();

}

 

5. 同时具有返回值、输入参数、输出参数的存储过程

存储过程:

CREATE PROCEDURE Categoriestest5

@id int output,

@CategoryName nvarchar(15)

AS

insert into dbo.Categories 

(CategoryName,Description,Picture)

values (@CategoryName,'test1',null)

set  @id = @@IDENTITY

return @@rowcount

GO

 

C#代码:

protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

        string conn = ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;

        SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest5";

        cmd.CommandType = CommandType.StoredProcedure;

        // 创建参数

        IDataParameter[] parameters = {

                new SqlParameter("@Id", SqlDbType.Int,4) ,

                new SqlParameter("@CategoryName", SqlDbType.NVarChar,15) ,

                new SqlParameter("rval", SqlDbType.Int,4)

            };

        // 设置参数类型

        parameters[0].Direction = ParameterDirection.Output;       // 设置为输出参数

        parameters[1].Value = "testCategoryName";                  // 给输入参数赋值

        parameters[2].Direction = ParameterDirection.ReturnValue;  // 设置为返回值

        // 添加参数

        cmd.Parameters.Add(parameters[0]);

        cmd.Parameters.Add(parameters[1]);

        cmd.Parameters.Add(parameters[2]);

 

        sqlconn.Open();

        // 执行存储过程并返回影响的行数

        Label1.Text = cmd.ExecuteNonQuery().ToString();

        sqlconn.Close();

        // 显示影响的行数,输出参数和返回值

        Label1.Text += "-" + parameters[0].Value.ToString() + "-" + parameters[2].Value.ToString();

}

 

6. 同时返回参数和记录集的存储过程

存储过程Categoriestest6

CREATE PROCEDURE Categoriestest6
@id int output,
@CategoryName nvarchar(15)
AS
insert into dbo.Categories 
(CategoryName,[Description],[Picture])
values (@CategoryName,'test1',null)
set  @id = @@IDENTITY
select * from Categories
return @@rowcount
GO

 

C#代码:

protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

        string conn = ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;

        SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest6";

        cmd.CommandType = CommandType.StoredProcedure;

        // 创建参数

        IDataParameter[] parameters = {

                new SqlParameter("@Id", SqlDbType.Int,4) ,

                new SqlParameter("@CategoryName", SqlDbType.NVarChar,15) ,

                new SqlParameter("rval", SqlDbType.Int,4)              

     // 返回值

            };

        // 设置参数类型

        parameters[0].Direction = ParameterDirection.Output;       

 // 设置为输出参数

        parameters[1].Value = "testCategoryName";                  

 // 给输入参数赋值

        parameters[2].Direction = ParameterDirection.ReturnValue;  

 // 设置为返回值

        // 添加参数

        cmd.Parameters.Add(parameters[0]);

        cmd.Parameters.Add(parameters[1]);

        cmd.Parameters.Add(parameters[2]);

 

        SqlDataAdapter dp = new SqlDataAdapter(cmd);

        DataSet ds = new DataSet();

        // 填充dataset

        dp.Fill(ds);

        // 显示结果集

        GridView1.DataSource = ds.Tables[0];

        GridView1.DataBind();

 

        Label1.Text = "";

        // 显示输出参数和返回值

        Label1.Text += parameters[0].Value.ToString() + "-" + parameters[2].Value.ToString();

}

 

7. 返回多个记录集的存储过程

存储过程7

CREATE PROCEDURE Categoriestest7
AS
select * from Categories
select * from Categories
GO

 

 

C#代码:

protected void Page_Load(object sender, EventArgs e)

    {

        fillGridView();

    }

 

    public void fillGridView() {

        string conn = ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;

        SqlConnection sqlconn = new SqlConnection(conn);

        SqlCommand cmd = new SqlCommand();

 

        cmd.Connection = sqlconn;

        cmd.CommandText = "Categoriestest7";

        cmd.CommandType = CommandType.StoredProcedure;

 

        SqlDataAdapter dp = new SqlDataAdapter(cmd);

        DataSet ds = new DataSet();

        // 填充dataset

        dp.Fill(ds);

        // 显示结果集1

        GridView1.DataSource = ds.Tables[0];

        GridView1.DataBind();

        // 显示结果集2

        GridView2.DataSource = ds.Tables[1];

        GridView2.DataBind();

}

 

Default.aspx:

<asp:GridView ID="GridView1" runat="server">

    </asp:GridView>

 

    <asp:GridView ID="GridView2" runat="server">

    </asp:GridView>

 

 

 

 

 

 

 

 

 

JDBC存储过程调用方式(ps:lib目录下放sqlserver的驱动

JDBC调用存储过程也是有四种情况:

本文主要是总结 如何实现 JDBC用SQLSERVER的存储过程,从以下情况分别介绍:

 [1]、只有输入IN参数,没有输出OUT参数

 [2]、既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)

 [3]、既有输入IN参数,也有输出OUT参数,输出是列表

 [4]、输入输出参数是同一个(IN OUT

 

【准备工作】

  创建一个测试表TMP_MICHAEL ,并插入数据,SQL如下:

create table TMP_MICHAEL

(

  USER_ID    VARCHAR(20),

  USER_NAME  VARCHAR(10),

  SALARY     decimal(8,2),

  OTHER_INFO VARCHAR(100)

)

 

insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)

values ('michael', 'Michael', 5000, 'http://sjsky.iteye.com');

insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)

values ('zhangsan', '张三', 10000, null);

insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)

values ('aoi_sola', '苍井空', 99999.99, 'twitter account');

insert into TMP_MICHAEL (USER_ID, USER_NAME, SALARY, OTHER_INFO)

values ('李四', '李四', 2500, null);

 

SQL SERVER jdbc 常量:

 private final static String DB_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

    private final static String DB_CONNECTION = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=TestDemo";

    private final static String DB_NAME = "sa";

private final static String DB_PWd = "qs@123456";

 

[]、只有输入IN参数,没有输出OUT参数

 

CREATE PROCEDURE TEST_MICHAEL_NOOUT

@USER_ID VARCHAR(20),

@USER_NAME VARCHAR(10),

@SALARY decimal(8,2),

@OTHER_INFO VARCHAR(100)

as

insert into dbo.TMP_MICHAEL

(USER_ID,USER_NAME,SALARY,OTHER_INFO)

values (@USER_ID,@USER_NAME,@SALARY,@OTHER_INFO)

Go

 

TmpMichael.java

package dao;

 

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

 

public class TmpMichael {

//参数

    private final static String DB_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

    private final static String DB_CONNECTION = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=TestDemo";

    private final static String DB_NAME = "sa";

    private final static String DB_PWd = "qs@123456";

    

    //调用函数

    public static void testProcNoOut() throws Exception {

        System.out.println("-------  start 测试调用存储过程:无返回值");

        Connection conn = null;

        CallableStatement callStmt = null;

        try {

            Class.forName(DB_DRIVER);

            conn = DriverManager.getConnection(DB_CONNECTION, DB_NAME, DB_PWd);

            // 存储过程 TEST_MICHAEL_NOOUT 其实是向数据库插入一条数据

            callStmt = conn.prepareCall("{call TEST_MICHAEL_NOOUT(?,?,?,?)}");

 

            // 参数index从1开始,依次 1,2,3...

            callStmt.setString(1, "jdbc");

            callStmt.setString(2, "JDBC");

            callStmt.setDouble(3, 8000.00);

            callStmt.setString(4, "http://sjsky.iteye.com");

            callStmt.execute();

            System.out.println("-------  Test End.");

        } catch (Exception e) {

            e.printStackTrace(System.out);

        } finally {

            if (null != callStmt) {

                callStmt.close();

            }

            if (null != conn) {

                conn.close();

            }

        }

    }

}

在index.jsp页面中添加入下代码

 

存储过程

 

<jsp:useBean id="TmpMichael" class="dao.TmpMichael"></jsp:useBean>

<%

TmpMichael.testProcNoOut();

%>

 

跑起这个应用:

存储过程

查看数据库:

存储过程

 

调用成功

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(存储过程)