C#开发Winform程序调用存储过程

数据表及数据准备:

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);
    }
}

到此这篇关于C#开发Winform程序调用存储过程的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SQL Server存储过程在C#中调用的简单实现方法

    0. 简介 [定义]:存储过程(Stored Procedure) 是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它. [优缺点]:存储过程优缺点都非常的明显!几乎每一篇讨论存储过程的文字,都是会说其他优点是balabala,缺点是balabala,然而最后作者的结论都是:"我不推荐使用存储过程". 具体的存储过程的优缺点这里就不详述了! 公司旧项目使用存储过程实现业

  • C# Ado.net实现读取SQLServer数据库存储过程列表及参数信息示例

    本文实例讲述了C# Ado.net读取SQLServer数据库存储过程列表及参数信息的方法.分享给大家供大家参考,具体如下: 得到数据库存储过程列表: select * from dbo.sysobjects where OBJECTPROPERTY(id, N'IsProcedure') = 1 order by name 得到某个存储过程的参数信息:(SQL方法) select * from syscolumns where ID in (SELECT id FROM sysobjects

  • C#中如何执行存储过程方法

    功能 :  根据调用的方法名称  反射动态调用  sql Command 的方法 复制代码 代码如下: /// <summary>    /// 存储过程的属性     /// ProcName 存储过程的名称    /// MethodName 执行SqlCommand 方法的名称    /// PrmList 存储过程的参数    /// </summary>    public class ExeProc    {        public string ProcName;

  • C#获取存储过程返回值和输出参数值的方法

    1.获取Return返回值 复制代码 代码如下: //存储过程//Create PROCEDURE MYSQL//     @a int,//     @b int//AS//     return @a + @b//GOSqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());conn.Open();SqlCommand MyC

  • 使用C#代码获取存储过程返回值

    废话不多说,直接给大家贴C#代码了. /// <summary> /// 执行存储过程,返回" 返回值" /// </summary> /// <param name="storedProcName">存储过程名</param> /// <param name="parameters">存储过程参数</param> /// <returns>执行存储过程的返回值&

  • C#执行存储过程并将结果填充到GridView的方法

    本文实例讲述了C#执行存储过程并将结果填充到GridView的方法.分享给大家供大家参考,具体如下: SelectSql sq = new SelectSql(); SqlConnection conn = new SqlConnection(sq.lc); conn.Open(); SqlDataAdapter rd = new SqlDataAdapter(); DataSet ds=new DataSet(); SqlCommand sqlcom = new SqlCommand("dbo

  • c#获取存储过程返回值示例分享

    存储过程: 复制代码 代码如下: CREATE  PROCEDURE [dbo].[Proc_GetInfo] @ywdm varchar(10), @value varchar(20) output AS begin set @value=Select top 1 createt From table Where ywdm=@ywdm end C#获取存储过程返回值: 复制代码 代码如下: var db = DatabaseFactory.CreateDatabase(); var cmd =

  • C#中常用的分页存储过程小结

    表中主键必须为标识列,[ID] int IDENTITY (1,1)//每次自增一 1.分页方案一:(利用Not In和SELECT TOP分页) 语句形式: 复制代码 代码如下: SELECT TOP 10 * FROM TestTable WHERE (ID NOT IN (SELECT TOP 20 id FROM TestTable ORDER BY id)) ORDER BY ID SELECT TOP 页大小 * FROM TestTable WHERE (ID NOT IN (SE

  • C#调用SQL Server中有参数的存储过程

    一.使用SqlParameter的方式 代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.SqlClient; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Syste

  • C#开发Winform程序调用存储过程

    数据表及数据准备: 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,Me

  • .Net6开发winform程序使用依赖注入

    .net  Blazor webassembly 和 webAPI 内建支持依赖注入, Winform 和 Console 应用虽然不带有依赖注入功能, 但增加依赖注入也很简单.  本文将示例如何为 WinForm 程序增加依赖注入特性, 实现通过DI容器获取Cofiguration 实例, 并读取appsettings.json文件. 安装依赖库, 有点多 Microsoft.Extensions.DependencyInjection 库, 依赖注入的类库 Microsoft.Extensi

  • .Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用

    中午没事,把去年刚毕业那会画的几张图翻出来了,大概介绍Winform应用程序运行的过程,以及TCP协议在Winform中的应用.如果有Windows消息机制等基础,很好理解这两张图. (1)Winform应用程序运行结构图 (2)TCP通讯协议在Winform程序中的应用示意图 熟悉整个程序的来龙去脉,编程的时候就会很轻松,不会云里雾里. 另附公司招聘面试题一份,用了几次,发现效果不好,不知啥原因 1.简述接口.抽象类的区别. 2.简述重载(overload)与重写(override)的区别.

  • 在ASP.NET中调用存储过程方法新解

    在使用.NET的过程中,数据库访问是一个很重要的部分,特别是在B/S系统的构建过程中,数据库操作几乎成为了一个必不可少的操作.调用存储过程实现数据库操作使很多程序员使用的方法,而且大多数的程序员都是能使用存储过程就使用存储过程,很少直接使用SQL语句,所以存储过程是很有用而且很重要的. 存储过程简介 简单的说,存储过程是由一些SQL语句和控制语句组成的被封装起来的过程,它驻留在数据库中,可以被客户应用程序调用,也可以从另一个过程或触发器调用.它的参数可以被传递和返回.与应用程序中的函数过程类似,

  • C#开发Winform实现窗体间相互传值

    目录 一.前言 二.公共属性 三.公共方法 四.委托 1.定义一个委托 2.实例化一个此委托类型的事件 3.定义要执行的方法 4.将方法绑定到事件 5.触发委托 一.前言 我们在做Winform窗体程序开发的时候,会经常遇到窗体之间相互传值.假设有下面的一个场景:一个主窗体和一个子窗体,点击主窗体上面的按钮给子窗体传值,并在子窗体上面显示出来,一般会有如下几种方式实现. 二.公共属性 我们可以在子窗体里面定义一个公共的属性,然后在父窗体里面给公共属性赋值,这样可以实现窗体之间传值,子窗体代码如下

  • C#开发Winform实现文件操作案例

    目录 一.文件对话框 (1)OpenFileDialog对话框 (2)SaveFileDialog对话框 (3)FolderBroswerDialog对话框 二.文件及文件夹操作 (1)文件常用操作 (2)文件夹常用操作 (3)文件夹的复制和移动 文件和流的概念: 读写文本文件最常用的类有: 读写文件操作的基本步骤为: 文件流对象: 文件读写器常用方法: 三.读写文本文件 四.序列化与反序列化 (1)序列化单个对象 (2)序列化集合 一.文件对话框 C#中共有三种文件对话框,分别用于不同的功能:

  • C#使用三层架构开发Winform的详细案例

    三层架构将整个业务应用划分为: (1)界面UI层 (2)业务逻辑层 (3)数据访问层 对于复杂的系统分层可以让结构更加清晰,模块更加独立,便于维护. 各层的任务: (1)数据访问层:负责数据库的操作. (2)业务逻辑层:实现功能模块的业务逻辑. (3)界面UI层:绘制界面,以及负责界面相关代码. (4)实体类:将数据库中的表转化为面向对象思想中的类. 一.案例需求 使用三层架构实现学生管理: (1)专业下拉框绑定专业表数据,网格控件绑定学生数据,并且点击"搜索"按钮可以多条件组合查询.

  • java编程调用存储过程中得到新增记录id号的实现方法

    本文实例讲述了java编程调用存储过程中得到新增记录id号的实现方法.分享给大家供大家参考,具体如下: 关于ms sql server2000的存储过程,主要作用是在表test中插入一条记录,然后得到新增加记录的id号. test表三个字段: ID:自动增长 yhm:用户名 字符串类型 kl: 密码   字符串类型 那么在java程序中如何调用这个存储过程才能实现,得到新增加记录的id号 存储过程如下: CREATE PROCEDURE yh_insert @yhm varchar(50),@k

  • ASP.NET也像WinForm程序一样运行的实现方法

    由于现在会使用WinForm的人是越来越少了,可能有时候做点小东西就只好用ASP.NET去完成了(喜欢控制台的朋友请不要顶针),如果是这样,悲剧就发生了:一个小工具(或者小的演示项目),发给朋友去用,总不至于让人家也装个IIS或者VS20XX吧?如果没有这二样,这种小工具还真不方便运行.怎么办?做过ASP.NET开发的人都知道:网站通常要布署到IIS上才能直接运行,当然也不排除你用VS打开项目并使用VS自带的WebDev.WebServer.exe来启动程序.这种方式难免有不方便的时候. 我平时

  • Android NDK开发简单程序分享(Hello Word!)

    在之前的博客中已经为大家介绍了,如何在win环境下配置DNK程序,本篇我将带大家实现一个简单的Hello jni程序,让大家真正感受一下NDK开发的魅力.这里我们选择使用C+JAVA开发Android程序,首先你必须了解C语言.JAVA语言以及Linux操作系统,这样可以帮助你开始上手,当然不是说你必须是大牛才能进行NDK开发,下面我们来一起实现一个简单的NDK程序. 第一步,创建Android工程 打开开发环境eclipse,在左侧空白区域,右键单击创建Android工程(非常简单,不再赘述)

随机推荐