数据表及数据准备:

create table Member
(
MemberId int primary key identity(1,1),
MemberAccount nvarchar(20) unique,
MemberPwd nvarchar(20),
MemberName nvarchar(20),
MemberPhone nvarchar(20)
)
truncate table Member insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values('liubei','123456','刘备','4659874564')
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values('guanyu','123456','关羽','42354234124')
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values('zhangfei','123456','张飞','41253445')
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values('zhangyun','123456','赵云','75675676547')
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values('machao','123456','马超','532523523')

本文以下内容都借助于前面封装的DBHelper类

一、调用exec语句执行存储过程

由于在SQL SERVER内部调用存储过程使用的方式是:

exec 存储过程名 参数1,参数2,参数3...

所以我们可以在C#中调用exec的sql语句,让此sql语句去调用存储过程,严格来说,此种方式并不能称之为C#调用存储过程,本质上仍然是调用的sql语句。

示例:

需求:采用调用存储过程的方式实现数据的显示以及数据的新增。

主要代码:

SQL存储过程代码:

--查询Member表所有数据的存储(没有参数)
create proc procSelectMember
as
select * from Member
go
exec procSelectMember --添加会员信息(有输入参数)
create proc procInsertMember
@acc nvarchar(20),
@pwd nvarchar(20),
@memName nvarchar(20),
@memPhone nvarchar(20)
as
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values(@acc,@pwd,@memName,@memPhone)
go
exec procInsertMember 'sunwukong','123456','孙悟空','13554856985'

数据显示C#代码:

private void BindData()
{
DBHelper.PrepareSql("exec procSelectMember");
this.dataGridView1.DataSource = DBHelper.ExecQuery();
}
private void Form1_Load(object sender, EventArgs e)
{
BindData();
}

数据新增C#代码:

private void btAdd_Click(object sender, EventArgs e)
{
DBHelper.PrepareSql(string.Format("exec procInsertMember '{0}','{1}','{2}','{3}'"
,this.txtAccount.Text,this.txtPwd.Text,this.txtNickName.Text,this.txtPhone.Text));
DBHelper.ExecNonQuery();
}

二、直接调用存储过程

调用存储过程需要将CommandType执行命令类型设置为CommandType.StoredProcedure存储过程。

(1)调用没有参数的存储过程

需求:实现数据的显示。

主要代码:

SQL存储过程代码:

--查询Member表所有数据的存储(没有参数)
create proc procSelectMember
as
select * from Member
go
--调用
exec procSelectMember

为了支持存储过程,给DBHelper添加方法:

public static void PrepareProc(string sql)
{
OpenConn(); //打开数据库连接
adp = new SqlDataAdapter(sql, conn);
adp.SelectCommand.CommandType = CommandType.StoredProcedure;
}

窗体代码:

private void BindData()
{
DBHelper.PrepareProc("procSelectMember");
this.dataGridView1.DataSource = DBHelper.ExecQuery();
}
private void Form1_Load(object sender, EventArgs e)
{
BindData();
}

(2)调用有输入参数的存储过程

需求:实现数据的新增。

主要代码:

SQL存储过程代码:

--添加会员信息(有输入参数)
create proc procInsertMember
@acc nvarchar(20),
@pwd nvarchar(20),
@memName nvarchar(20),
@memPhone nvarchar(20)
as
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values(@acc,@pwd,@memName,@memPhone)
go
--调用
exec procInsertMember 'sunwukong','123456','孙悟空','13554856985'

窗体代码:

private void btAdd_Click(object sender, EventArgs e)
{
DBHelper.PrepareProc("procInsertMember");
DBHelper.SetParameter("acc", this.txtAccount.Text);
DBHelper.SetParameter("pwd",this.txtPwd.Text);
DBHelper.SetParameter("memName", this.txtNickName.Text);
DBHelper.SetParameter("memPhone", this.txtPhone.Text);
DBHelper.ExecNonQuery();
}

(3)调用有输入和输出参数的存储过程

需求:输入用户名,点击"查询电话"按钮,在下面显示姓名和号码。

主要代码:

SQL存储过程:

--根据账号查询姓名和电话(有输入参数,有输出参数)
create proc procGetInfoByAcc
@acc nvarchar(20),
@memName nvarchar(20) output,
@phone nvarchar(20) output
as
select @memName = (select MemberName from Member where MemberAccount=@acc)
select @phone = (select MemberPhone from Member where MemberAccount=@acc)
go
--调用
declare @name nvarchar(20)
declare @phone nvarchar(20)
exec procGetInfoByAcc 'machao',@name output,@phone output
select @name,@phone

为了支持输出参数,给DBHelper添加方法:

/// <summary>
/// 设置输出参数(不指定长度,适合非字符串)
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">参数类型</param>
public static void SetOutParameter(string parameterName, SqlDbType dbType)
{
parameterName = "@" + parameterName.Trim();
SqlParameter parameter = new SqlParameter(parameterName, dbType);
parameter.Direction = ParameterDirection.Output;
adp.SelectCommand.Parameters.Add(parameter);
}
/// <summary>
/// 设置输出参数(指定长度,适合字符串)
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">参数类型</param>
/// <param name="size">参数长度</param>
public static void SetOutParameter(string parameterName, SqlDbType dbType, int size)
{
parameterName = "@" + parameterName.Trim();
SqlParameter parameter = new SqlParameter(parameterName, dbType, size);
parameter.Direction = ParameterDirection.Output;
adp.SelectCommand.Parameters.Add(parameter);
}
/// <summary>
/// 获取参数内容值
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <returns>参数值</returns>
public static object GetParameter(string parameterName)
{
parameterName = "@" + parameterName.Trim();
return adp.SelectCommand.Parameters[parameterName].Value;
}

窗体代码:

private void btSearch_Click(object sender, EventArgs e)
{
DBHelper.PrepareProc("procGetInfoByAcc");
DBHelper.SetParameter("acc", this.txtAccount.Text);
DBHelper.SetOutParameter("memName", SqlDbType.NVarChar, 20);
DBHelper.SetOutParameter("phone", SqlDbType.NVarChar, 20);
DBHelper.ExecNonQuery();
this.lblName.Text = "姓名:" + DBHelper.GetParameter("memName").ToString();
this.lblPhone.Text = "电话:" + DBHelper.GetParameter("phone").ToString();
}

(4)调用有输入输出参数的存储过程

需求:密码升级,传入用户名和密码;如果用户名密码正确,并且密码长度<8,自动升级成8位密码。

主要代码:

SQL存储过程(SQLSERVER中output参数直接传入值即可以做输入参数,也可以做输出参数):

--密码升级,传入用户名和密码,如果用户名密码正确,并且密码长度<8,自动升级成8位密码
--有输入输出参数(密码作为输入参数也作为输出参数)
select FLOOR(RAND()*10) --0-9之间随机数
create proc procPwdUpgrade
@acc nvarchar(20),
@pwd nvarchar(20) output
as
if not exists(select * from Member where MemberAccount=@acc and MemberPwd=@pwd)
set @pwd = ''
else
begin
if len(@pwd) < 8
begin
declare @len int = 8- len(@pwd)
declare @i int = 1
while @i <= @len
begin set @pwd = @pwd + cast(FLOOR(RAND()*10) as varchar(1))
set @i = @i+1
end
update Member set MemberPwd = @pwd where MemberAccount=@acc
end
end
go
--调用
declare @pwd nvarchar(20) = '123456'
exec procPwdUpgrade 'liubei',@pwd output
select @pwd

为了支持输入输出参数,给DBHelper添加方法:

/// <summary>
/// 设置输入输出参数(不指定长度,适合非字符串)
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">参数类型</param>
public static void SetInOutParameter(string parameterName, SqlDbType dbType, object parameterValue)
{
parameterName = "@" + parameterName.Trim();
SqlParameter parameter = new SqlParameter(parameterName, dbType);
parameter.Value = parameterValue;
parameter.Direction = ParameterDirection.InputOutput;
adp.SelectCommand.Parameters.Add(parameter);
}
/// <summary>
/// 设置输入输出参数(指定长度,适合字符串)
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">参数类型</param>
/// <param name="size">参数长度</param>
public static void SetInOutParameter(string parameterName, SqlDbType dbType, int size, object parameterValue)
{
parameterName = "@" + parameterName.Trim();
SqlParameter parameter = new SqlParameter(parameterName, dbType, size);
parameter.Value = parameterValue;
parameter.Direction = ParameterDirection.InputOutput;
adp.SelectCommand.Parameters.Add(parameter);
}

窗体代码:

//密码升级,传入用户名和密码,
//如果用户名密码正确,并且密码长度<8,自动升级成8位密码
private void btUpgrade_Click(object sender, EventArgs e)
{
DBHelper.PrepareProc("procPwdUpgrade");
DBHelper.SetParameter("acc", this.txtAccount.Text);
DBHelper.SetInOutParameter("pwd", SqlDbType.NVarChar, 20, this.txtPwd.Text);
DBHelper.ExecNonQuery();
this.lblNewPwd.Text = DBHelper.GetParameter("pwd").ToString();
}

(5)调用有返回值的存储过程

SQLSERVER存储过程返回值只能是整数。

需求:实现数据的新增,由SQLSERVER返回执行的状态。

主要代码:

SQL存储过程代码:

--添加会员信息(有返回值)
create proc procInsertMember
@acc nvarchar(20),
@pwd nvarchar(20),
@memName nvarchar(20),
@memPhone nvarchar(20)
as
insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone)
values(@acc,@pwd,@memName,@memPhone)
declare @myErr int = @@error
if @myErr = 0
return 1
else if @myErr = 2627 --唯一约束
return -1
else
return -100
go
--调用
declare @return int
exec @return = procInsertMember 'sunwukong','123456','孙悟空','13554854785'
print @return

为了支持返回值,给DBHelper添加方法:

/// <summary>
/// 设置返回值参数
/// </summary>
/// <param name="parameterName">参数名称</param>
public static void SetReturnParameter(string parameterName)
{
parameterName = "@" + parameterName.Trim();
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = parameterName;
parameter.Direction = ParameterDirection.ReturnValue;
adp.SelectCommand.Parameters.Add(parameter);
}

窗体代码:

private void btAdd_Click(object sender, EventArgs e)
{
try
{
DBHelper.PrepareProc("procInsertMember");
DBHelper.SetParameter("acc", this.txtAccount.Text);
DBHelper.SetParameter("pwd", this.txtPwd.Text);
DBHelper.SetParameter("memName", this.txtNickName.Text);
DBHelper.SetParameter("memPhone", this.txtPhone.Text);
DBHelper.SetReturnParameter("returnValue");
DBHelper.ExecNonQuery();
int result = (int)DBHelper.GetParameter("returnValue");
if (result == 1)
MessageBox.Show("添加成功!");
}
catch (Exception ex)
{
int result = (int)DBHelper.GetParameter("returnValue");
if (result == -1)
MessageBox.Show("用户名重名了,违反了唯一约束!");
if (result == -100)
MessageBox.Show(ex.Message);
}
}

Winform调用存储过程的更多相关文章

  1. spring data jpa 调用存储过程

    网上这方面的例子不是很多,研究了一下,列出几个调用的方法. 假如我们有一个mysql的存储过程 CREATE DEFINER=`root`@`localhost` PROCEDURE `plus1in ...

  2. myabatis oracle 调用存储过程返回list结果集

    Mapper.xml 配置 <resultMap type="emp" id="empMap"> <id property="emp ...

  3. C#winForm调用WebService的远程接口

    Web Service 的创建简单编码.发布和部署 上一篇详细概述了WebService的创建,编码,发布和部署,那么作为客户端的程序如何访问远程端的WebService 接下来看一下具体步骤:   ...

  4. IBatis.Net使用总结(四)-- IBatis 调用存储过程

    IBatis 调用存储过程 http://www.cnblogs.com/jeffwongishandsome/archive/2010/01/10/1543219.html http://www.c ...

  5. SQL SERVER使用ODBC 驱动建立的链接服务器调用存储过程时参数不能为NULL值

    我们知道SQL SERVER建立链接服务器(Linked Server)可以选择的驱动程序非常多,最近发现使用ODBC 的 Microsoft OLE DB 驱动程序建立的链接服务器(Linked S ...

  6. 【Java EE 学习 29 下】【JDBC编程中操作Oracle数据库】【调用存储过程的方法】

    疑问:怎样判断存储过程执行之后返回值是否为空. 一.连接oracle数据库 1.需要的jar包:在安装的oracle中就有,所以不需要到官网下载,我的oracle11g下:D:\app\kdyzm\p ...

  7. MyBatis学习总结(六)——调用存储过程(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013518.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存 ...

  8. C# 调用存储过程操作 OUTPUT参数和Return返回值

    本文转载:http://www.cnblogs.com/libingql/archive/2010/05/02/1726104.html 存储过程是存放在数据库服务器上的预先编译好的sql语句.使用存 ...

  9. jdbc调用存储过程和函数

    1.调用存储过程 public class CallOracleProc { public static void main(String[] args) throws Exception{ Stri ...

随机推荐

  1. 基础学习:关于this在派生类构造函数中的理解

    https://www.cnblogs.com/Bear-Study-Hard/archive/2006/01/09/313551.html 看了上面这篇文章有感,特做了个小样板,以加深对于this在 ...

  2. JOISC 2017

    Day1 「JOISC 2017 Day 1」开荒者 首先观察部分分发现分档很多,于是考虑一步步思考上来. 首先有一点关键观察(一): 风吹的顺序是无所谓的,令分别往东.西.南.北吹了 \(r, l, ...

  3. Swift循环的介绍

    循环的介绍 在开发中经常会需要循环 常见的循环有:for/while/do while. 这里我们只介绍for/while,因为for/while最常见 for循环的写法 最常规写法 // 传统写法 ...

  4. Java中File类的方法详解

    File类也是Java中一个比较重要的类,通过他我们可以实现对文件的一系列操作,其内置了很多方法,下面我将按方法的功能分块,逐一讲解: 快速导航 构造方法 常用方法 创建目录 判断 `is...` t ...

  5. linux_16

    对常用I/O模型进行比较说明 nginx中的模块分类及常见核心模块有哪些 描述nginx中worker_processes.worker_cpu_affinity.worker_rlimit_nofi ...

  6. Solution -「CF 1025D」Recovering BST

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\),问是否存在一棵二叉搜索树,使得其中序遍历为 \(\{a_n\}\),且相邻接的两点不互素.   ...

  7. ssh 主机之间免密配置脚本

    文章目录 单向免密 `expect` 免交互 `sshpass` 免交互 相互免密 单向免密 expect 免交互 注意修改脚本内的 your_password 为 远程主机用户的密码 脚本内的 &q ...

  8. c++ Message与Folder 拷贝 析构(没有动态空间的类)

    c++ Message与Folder 拷贝 析构(没有动态空间的类) 1.两个类里边分别保存一个对方的set表,当前类有拷贝或者销毁时需要更新另一个类的set表. 2.两个类都需要访问对方的priva ...

  9. Python基础—基础数据类型int、bool、str(Day3)

    一.int 数字 用于计算,+ - * / % **等 bit_lenth():转化成二进制的最小位数. i=4 print(i.bit_length())执行结果:3 1   0000 0001 2 ...

  10. Redis 中常见的集群部署方案

    Redis 的高可用集群 前言 几种常用的集群方案 主从集群模式 全量同步 增量同步 哨兵机制 什么是哨兵机制 如何保证选主的准确性 如何选主 选举主节点的规则 哨兵进行主节点切换 切片集群 Redi ...