C# 高阶语法 —— Winfrom链接SQL数据库的存储过程

存储过程在应用程序端的使用的优点

        1 如果sql语句直接写在客户端,以一个字符串的形式体现的,提示不友好,会导致效率降低
        2 sql语句写在客户端,可以利用sql注入进行攻击,为了安全性,可以把sql封装在服务器存储过程,在客户端进行

SQL自定义无参数存储过程:

创建存储过程 usp_ScoreQuery1
-- 查询考试成绩,显示:学号、姓名、班级、总成绩,并按成绩的总分高低排序。
-- 统计分析考试成绩,显示班级名称、C#平均分、数据库平均分,按照班级分组实现。

 use SMDB
 go
 if exists (select * from sysobjects where name = 'usp_ScoreQuery1')
 drop procedure usp_ScoreQuery1
 go
 create procedure usp_ScoreQuery1
 as
 	   -- 查询考试成绩
 	   select Students.StudentId,StudentName,ClassName, ScoreSum = (CSharp + SqlserverDB) from Students
 	   inner join StudentClass on StudentClass.ClassId = Students.ClassId
 	   inner join ScoreList on ScoreList.StudentId = Students.StudentId
 	   order by ScoreSum DESC
 	   -- 分析考试信息
 	   select ClassName,C#Avg=AVG(CSharp),DBAvg=AVG(SqlserverDB) from ScoreList
 	   inner join Students on Students.StudentId = ScoreList.StudentId
 	   inner join StudentClass on StudentClass.ClassId = Students.ClassId
 	   group by ClassName
 	   order by ClassName
 go

针对上面实现的效果,继续修改,改为参数可以带默认值 

use SMDB
go
if exists (select * from sysobjects where name = 'usp_ScoreQuery4')
drop procedure usp_ScoreQuery4
go
create procedure usp_ScoreQuery4
	-- 带默认值
	@CSharp int = 60,
	@SqlserverDB int = 60
as
	select Students.StudentId,StudentName,CSharp as C#,SqlserverDB as DB from ScoreList
	inner join Students on Students.StudentId = ScoreList.StudentId
	where CSharp < @CSharp or SqlserverDB < @SqlserverDB
go

-- 调用参数带默认值的存储过程
use SMDB
go
exec usp_ScoreQuery4 -- 两个都走的默认值
exec usp_ScoreQuery4 70,80 -- 第二个参数取默认值
exec usp_ScoreQuery4 @SqlserverDB = 70 -- 第一个参数取默认值
exec usp_ScoreQuery4 default,70 -- 第一个参数取默认值(同上)

3. 自定义带输出参数的存储过程
-- 问题:查询考试成绩,要求自定义分数线,显示查询列表,并输出缺考总人数、不及格总人数?

use SMDB
go
if exists (select * from sysobjects where name = 'usp_ScoreQuery5')
drop procedure usp_ScoreQuery5
go
create procedure usp_ScoreQuery5
	-- 输出参数(习惯:输出参数放在输入参数的前面)
	@AbsentCount int output, -- 缺考总人数
	@FailCount int output, -- 不及格总人数
	-- 输入参数
	@CSharp int = 60, -- CSharp分数线
	@SqlserverDB int = 60 -- SqlserverDB分数线
as
	-- 查询考试成绩,要求自定义分数线
	select Students.StudentId,StudentName,CSharp as C#,SqlserverDB as DB from ScoreList
	inner join Students on Students.StudentId = ScoreList.StudentId
	where CSharp < @CSharp or SqlserverDB < @SqlserverDB
	-- 缺考总人数
	select @AbsentCount = count(*) from Students where StudentId not in (select StudentId from ScoreList)
	-- 不及格总人数
	select @FailCount = count(*) from ScoreList where CSharp < @CSharp or SqlserverDB < @SqlserverDB
go

-- 调用参数带默认值的存储过程
use SMDB
go
-- 首先定义输出参数(命名可以和上面的保持一致,不一样也行)
declare @AbsentCount int, @FailCount int
-- 调用存储过程时,输出参数后面也必须加上 output 关键字
exec usp_ScoreQuery5 @AbsentCount output,@FailCount output 
select @AbsentCount as 缺考总人数,@FailCount as 不及格总人数
-- 打印一下结果
print @AbsentCount
print @FailCount

链接SQL数据库

public string connString = @"Server=.;DataBase=SMDB;Uid=sa;Pwd=123456";

 搭建Winfrom窗体 

一:无参数的存储过程的调用 

  不带参数存储过程的使用 

        1指定存储过程名称
        string proceName = "usp_ScoreQuery5";
        2创建指令对象传递连接对象和存储过程
        SqlCommand cmd = new SqlCommand(proceName,conn);
        3 指定指令执行类型
        cmd.CommandType = CommandType.StoredProcedure;
        4 执行指令
        SqlDataReader dr = cmd.ExecuteReader();

 private void button1_Click(object sender, EventArgs e)
 {
     //1 定义存储过程名称
     string proceName = "usp_ScoreQuery1";
     //2 创建一个指令对象
     SqlCommand cmd = new SqlCommand();
     //3 添加执行sql语句和设置连接对象
     cmd.CommandText = proceName;// 添加执行的sql
     cmd.Connection = conn; //设置连接对象
     //4 执行命令类型
     cmd.CommandType = System.Data.CommandType.StoredProcedure;
     // 5 取出数据
     List<Model1> model1s = new List<Model1>();// 存储第一个表的数据
     List<Model2> models2 = new List<Model2>();//存储第二个表的数据
     try
     {
         SqlDataReader dr = cmd.ExecuteReader(); // 读取数据库数据
         while (dr.Read())
         {
             model1s.Add(new Model1() { 
                 StudentId =Convert.ToInt32( dr["StudentId"]),
                 StudentName = dr["StudentName"].ToString(),
                 ClassName = dr["ClassName"].ToString(),
                 ScoreNum = Convert.ToInt32(dr["ScoreSum"])
             });
         }
         //如果有第二个数据源 读取第二个select
         if (dr.NextResult())
         {
             while (dr.Read())
             {
                 models2.Add(new Model2() {
                     ClassName = dr["ClassName"].ToString(),
                     CSharpAvg = Convert.ToInt32(dr["C#Avg"]),
                     DBAvg   = Convert.ToInt32(dr["DBAvg"]),
                 });
             }
         }
         dr.Close();
         this.dataGridView1.DataSource = model1s;
         this.dataGridView2.DataSource = models2;
     }
     catch
     {
         throw;
     }
 }
二:带输入参数的存储过程的使用

带输入参数的存储过程的调用

        1指定存储过程名称
                string proceName = "usp_ScoreQuery5";
        2创建指令对象传递连接对象和存储过程
                SqlCommand cmd = new SqlCommand(proceName,conn);
        3 指定指令执行类型
                cmd.CommandType = CommandType.StoredProcedure;
        4 添加输入参数
                cmd.Parameters.Add(new SqlParameter()
                    {
                        ParameterName = "@CSharp",
                        Direction = ParameterDirection.Input,
                        SqlDbType = SqlDbType.Int,
                        Value = 80
                    });
        5执行指令
                SqlDataReader dr = cmd.ExecuteReader();

private void button2_Click(object sender, EventArgs e)
{
    //1 指明存储过程
    string proceName = "usp_ScoreQuery4";
    //2 创建指令对象
    SqlCommand cmd = new SqlCommand();
    //3 设置连接和设置执行过程
    cmd.Connection = conn; 
    cmd.CommandText = proceName;
    //4  执行类型
    cmd.CommandType = CommandType.StoredProcedure;

    //5 设置输入参数
    //定义参数方法1
    SqlParameter csharp = new SqlParameter();
    csharp.ParameterName = "@CSharp";// 设置csharp是存储过程中对应@CSharp输入参数
    csharp.Direction = ParameterDirection.Input;//设置为输入参数
    csharp.Value = 180;// 设置参数的值为70
    csharp.SqlDbType = SqlDbType.Int; //设置参数类型
    cmd.Parameters.Add(csharp); // 把输入参数添加到参数列表里面

    // 定义参数方法2 @SqlserverDB
    cmd.Parameters.Add(new SqlParameter() { 
        ParameterName = "@SqlserverDB",
        Direction = ParameterDirection.Input,
        Value = 180,
        SqlDbType = SqlDbType.Int,
    });

    // 6 获取数据
    List<Model3> list = new List<Model3>();
    try
    {
        SqlDataReader dr = cmd.ExecuteReader();
        while (dr.Read())
        {
            list.Add(new Model3()
            {
                StudentId = Convert.ToInt32(dr["StudentId"]),
                StudentName = dr["StudentName"].ToString(),
                CSharp = Convert.ToInt32(dr["C#"]),
                DB = Convert.ToInt32(dr["DB"]),
            });
        }
        dr.Close();
        this.dataGridView1.DataSource = list;
    }
    catch
    {
        throw;
    }
}
三:调用带输出参数的存储过程 对应的是model3对象

带输入参数带输出参数的调用

添加输出参数即可
     cmd.Parameters.Add(new SqlParameter()
            {
                ParameterName = "@AbsentCount",
                Direction = ParameterDirection.Output,
                SqlDbType = SqlDbType.Int,
            });
   获取输出参数的值
        cmd.Parameters["@AbsentCount"].Value.ToString()

private void button3_Click(object sender, EventArgs e)
{
    string proceName = "usp_ScoreQuery5";
    SqlCommand cmd = new SqlCommand(proceName,conn);
    //cmd.CommandText = proceName;
    //cmd.Connection = conn;
    cmd.CommandType = CommandType.StoredProcedure;

    //设置输出参数
    cmd.Parameters.Add(new SqlParameter() { 
        ParameterName= "@AbsentCount",
        Direction = ParameterDirection.Output,
        SqlDbType=SqlDbType.Int,
    });
    cmd.Parameters.Add(new SqlParameter()
    {
        ParameterName = "@FailCount",
        Direction = ParameterDirection.Output,
        SqlDbType = SqlDbType.Int,
    });
    //输入参数
    cmd.Parameters.Add(new SqlParameter()
    {
        ParameterName = "@CSharp",
        Direction = ParameterDirection.Input,
        SqlDbType = SqlDbType.Int,
        Value = 80
    });
    cmd.Parameters.Add(new SqlParameter()
    {
        ParameterName = "@SqlserverDB",
        Direction = ParameterDirection.Input,
        SqlDbType = SqlDbType.Int,
        Value = 80
    });

    //取数据
    List<Model3> list = new List<Model3>();
    SqlDataReader dr = cmd.ExecuteReader();
    while (dr.Read())
    {
        list.Add(new Model3()
        {
            StudentId = Convert.ToInt32(dr["StudentId"]),
            StudentName = dr["StudentName"].ToString(),
            CSharp = Convert.ToInt32(dr["C#"]),
            DB = Convert.ToInt32(dr["DB"]),
        });
    }
    dr.Close();
    this.dataGridView1.DataSource = list;
    //输出参数的值怎么取? 缺考总人数? 不及格人数?
    this.label1.Text = "缺考总人数:" + cmd.Parameters["@AbsentCount"].Value.ToString() + "人";
    this.label2.Text = "不及格总人数:" + cmd.Parameters["@FailCount"].Value.ToString() + "人";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/418531.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

H3C防火墙安全授权导入

一、防火墙授权概述 前面我们已经了解了一些防火墙的基本概念&#xff0c;有讲过防火墙除了一些基本功能&#xff0c;还有一些高级安全防护&#xff0c;但是这些功能需要另外独立授权&#xff0c;不影响基本使用。这里以H3C防火墙为例进行大概了解下。 正常情况下&#xff0c;防…

01-prometheus监控系统-安装部署prometheus

一、准备环境 主机名ip配置prometheus-server3110.0.0.311核1g-20GBprometheus-server3210.0.0.311核1g-20GBprometheus-server3310.0.0.311核1g-20GB 二、下载/上传软件包 1&#xff0c;软件包地址 这里给大家准备了百度云盘的安装包&#xff1b; 链接&#xff1a;https:/…

upload-Labs靶场“1-5”关通关教程

君衍. 一、环境搭建二、第一关 前端JS检测后缀1、源码分析2、禁用浏览器JS上传3、burp抓包修改 三、第二关 MIME头验证1、源码分析2、burp抓包绕过 四、第三关 PHP3绕过1、源码分析2、PHP3绕过 五、第四关 .htaccess重写绕过1、源码分析2、.htaccess复写 六、第五关 黑名单大小…

VPP学习之配置VXLAN隧道

VPP学习之配置VXLAN隧道 一、VXLAN技术 VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;&#xff0c;是由IETF定义的NVO3&#xff08;Network Virtualization over Layer 3&#xff09;标准技术之一&#xff0c;是对传统VLAN…

互动多媒体内容的魔法:如何让你的网页活起来

互动多媒体内容的魔法&#xff1a;如何让你的网页活起来 前言 在之前的文章中&#xff0c;我们探讨了网页结构中的基础介绍&#xff0c;本文将介绍如何通过简单的交互增强用户体验&#xff0c;包括图像大小的动态切换&#xff0c;以及音视频内容的播放控制来介绍网页多媒体的具…

测试:4核8G服务器并发数,支持多少人?

腾讯云4核8G服务器支持多少人在线访问&#xff1f;支持25人同时访问。实际上程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&#xff0c;假设公网带宽太小&#xff0c;流量直接卡在入口&#xff0c;4核8G配置的CPU内存也会造成计算…

出现 ‘vue‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件的解决方法(图文界面)

目录 前言1. 问题所示2. 原理分析3. 解决方法前言 由于Java转全栈,对此前端的细节点都比他人更加注意,所以此处记录更有用的信息!(小白都能看懂) 1. 问题所示 出现如下问题: F:\vue_project>vue -version vue 不是内部或外部命令,也不是可运行的程序 或批处理文件…

网关kong记录接口处理请求和响应插件 tcp-log-with-body的安装

tcp-log-with-body 介绍 Kong的tcp-log-with-body插件是一个高效的工具&#xff0c;它能够转发Kong处理的请求和响应。这个插件非常适用于需要详细记录API请求和响应信息的情景&#xff0c;尤其是在调试和排查问题时。 软件环境说明 kong version 2.1.4 - 2.8.3 [可用亲测]C…

Windows Docker 部署 Redis

部署 Redis 打开 Docker Desktop&#xff0c;切换到 Linux 内核。然后在 PowerShell 执行下面命令&#xff0c;即可启动一个 redis 服务 docker run -d --name redis -p 6379:6379 redis-如果需要自启动&#xff0c;加 --restart always 参数即可。 连接 Redis 使用客户端连…

数据中心GPU集群高性能组网技术分析

数据中心GPU集群组网技术是指将多个GPU设备连接在一起&#xff0c;形成一个高性能计算的集群系统。通过集群组网技术&#xff0c;可以实现多个GPU设备之间的协同计算&#xff0c;提供更大规模的计算能力&#xff0c;适用于需要大规模并行计算的应用场景。 常用的组网技术&…

【Python笔记-设计模式】状态模式

一、说明 状态模式是一种行为设计模式&#xff0c;用于解决对象在不同状态下具有不同行为 (一) 解决问题 在对象行为根据对象状态而改变时&#xff0c;规避使用大量的条件语句来判断对象的状态&#xff0c;提高系统可维护性 (二) 使用场景 当对象的行为取决于其状态&#…

NPN型三极管与PNP型三极管基本原理

NPN型三极管与PNP型三极管基本原理 文章目录 NPN型三极管与PNP型三极管基本原理一、三极管二、结构三、工作原理四、基本应用五、总计 一、三极管 三极管是电子电路中最基本、最常见、重要的器件&#xff0c;其主要功能是对电流的放大和开关作用&#xff0c;从半导体结构上可以…

全国夜间灯光指数数据、GDP密度分布、人口密度分布、土地利用数据、降雨量数据

引言 DMSP/OLS的1992-2013年全球遥感影像&#xff0c;包括三种非辐射定标的夜间灯光影像。三种全年平均影像分别是&#xff1a;无云观测频数影像、平均灯光影像和稳定灯光影像。目前地理遥感生态网可提供全国稳定灯光影像免费下载。稳定灯光影像是标定夜间平均灯光强度的年度栅…

HCIA-HarmonyOS设备开发认证V2.0-习题

目录 习题一习题二&#xff08;待续...&#xff09;坚持就有收获 习题一 # HarmonyOS简介 1. 以下哪几项属于OpenHarmony的技术特性&#xff1f;&#xff08;&#xff09;A. 统一OS&#xff0c;弹性部署B. 一次开发&#xff0c;多端部署C. 硬件互助&#xff0c;资源共享2. Ope…

Ansible get_url模块 get_url模块用于将文件或软件从http、https或ftp下载到本地节点上

目录 常用参数&#xff1a;案例验证 常用参数&#xff1a; dest&#xff1a; 指定将文件下载的绝对路径—必须 url&#xff1a; 文件的下载地址&#xff08;网址&#xff09;—必须 url_username: 用于http基本认证的用户名 url_password&#xff1a; 用于http基本认证的密码 v…

Springboot解决模块化架构搭建打包错误找不到父工程

Springboot解决模块化架构搭建打包错误找不到父工程 一、情况一找不到父工程依赖1、解决办法 二、情况二子工程相互依赖提示"程序包xxx不存在" 一、情况一找不到父工程依赖 报错信息 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:…

最新精心整理Android面试题,Android未来路在何方

我们程序员经常迷茫于有太多东西要学&#xff0c;有些找不到方向、不知所措。 很多程序员都愿意说&#xff0c;我想变得更好&#xff0c;但是更好是什么却很模糊&#xff0c;同时我们又不知道该怎么样去做。我们的生命如此短暂&#xff0c;作为程序员的职业生涯可能会更短。所…

海量物理刚体 高性能物理引擎Unity Physics和Havok Physics的简单性能对比

之前的博客中我们为了绕过ECS架构&#xff0c;相当于单独用Batch Renderer Group实现了一个精简版的Entities Graphics&#xff0c;又使用Jobs版RVO2实现了10w人同屏避障移动。 万人同屏对抗割草 性能测试 PC 手机端 性能表现 弹幕游戏 海量单位同屏渲染 锁敌 避障 非ECS 那么有…

react 原理揭秘

1.目标 A. 能够知道setState()更新数据是异步的 B. 能够知道JSX语法的转化过程 C. 能够说出React组件的更新机制 D. 能够对组件进行性能优化 E. 能够说出虚拟DOM和Diff算法 2.目录 A. setState()的说明 B. JSX语法的转化过程 C. 组件更新机制 D. 组件性能优化 E. 虚拟DOM和D…

xss高级靶场

一、环境 XSS Game - Ma Spaghet! | PwnFunction 二、开始闯关 第一关 看看代码 试一下直接写 明显进来了为什么不执行看看官方文档吧 你不执行那我就更改单标签去使用呗 ?somebody<img%20src1%20onerror"alert(1)"> 防御&#xff1a; innerText 第二关…