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

news2024/10/7 18:31:31

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

        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() + "人";
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

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

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

CUDA C:查看GPU设备信息

相关阅读 CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 了解自己设备的性能是很有必要的&#xff0c;为此CUDA 运行时(runtime)API给用户也提供了一些查询设备信息的函数&#xff0c;下面的函数用于查看GPU设备的一切信息。 …

挑战30天学完Python:Day29 API开发

&#x1f389; 本系列为Python基础学习&#xff0c;原稿来源于 30-Days-Of-Python 英文项目&#xff0c;大奇主要是对其本地化翻译、逐条验证和补充&#xff0c;想通过30天完成正儿八经的系统化实践。此系列适合零基础同学&#xff0c;或仅了解Python一点知识&#xff0c;但又没…

如何在Node.js中使用定时器

在Node.js中使用定时器是一项常见且重要的任务&#xff0c;特别是在需要执行定时任务或者轮询操作的情况下。Node.js提供了多种方式来实现定时器功能&#xff0c;包括setTimeout、setInterval和setImmediate等方法。本篇博客将介绍如何在Node.js中使用这些定时器&#xff0c;并…

【STM32】STM32学习笔记-独立看门狗和窗口看门狗(47)

00. 目录 文章目录 00. 目录01. WDG概述02. 独立看门狗相关API2.1 IWDG_WriteAccessCmd2.2 IWDG_SetPrescaler2.3 IWDG_SetReload2.4 IWDG_ReloadCounter2.5 IWDG_Enable2.6 IWDG_GetFlagStatus2.7 RCC_GetFlagStatus 03. 独立看门狗接线图04. 独立看门狗程序示例105. 独立看门…

mysql缓存机制面试题,学海无涯

二、我们先来看看这份笔记到底有什么 1、先把kubernetes跑起来&#xff08;先跑起来创建kubernetes集群部署应用访问应用Scale应用滚动更新&#xff09; 2、重要概念 3、部署kubernetes Cluster&#xff08;安装docker安装 kubelet.kubeadm和 kubectll用kubeadm 创建cluster&a…

【力扣hot100】刷题笔记Day18

前言 晚上巩固一下今天的回溯题&#xff0c;基础不牢地动山摇&#xff0c;po一张代码随想录总结的 组合补充 77. 组合 - 力扣&#xff08;LeetCode&#xff09; class Solution:def combine(self, n: int, k: int) -> List[List[int]]:path []res []def backtrack(star…

航拍无人机技术,航拍无人机方案详解,无人机摄影技术

航拍无人机是利用遥控技术和摄像设备&#xff0c;在空中进行拍摄和录像的无人机。这种无人机通常具有高清摄像设备、图像传输设备、GPS定位系统、智能控制系统等&#xff0c;可以轻松实现各种拍摄角度和高度&#xff0c;广泛应用于影视制作、旅游景区航拍、城市规划、环保监测等…

CryoEM - 使用 cryoSPARC 基于单颗粒图像从头重构蛋白质三维结构

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/136384544 基于冷冻电镜单颗粒图像重构蛋白质三维结构,利用冷冻电镜技术测定生物大分子结构的方法。原理是从冷冻电镜获得大量同一种蛋白质分子的二维投影图…

计算机组成原理-第一/二章 概述和数据的表示和运算【期末复习|考研复习】

前言 总结整理不易&#xff0c;希望大家点赞收藏。 给大家整理了一下计算机组成原理中的重点概念&#xff0c;以供大家期末复习和考研复习的时候使用。 参考资料是王道的计算机组成原理和西电的计算机组成原理。 计算机组成原理系列文章传送门&#xff1a; 第一/二章 概述和数据…

适用Java SpringBoot项目的分布式锁

在分布式系统中&#xff0c;常用到分布式锁&#xff0c;它有多中实现方式&#xff0c;如&#xff1a;基于redis&#xff0c;database&#xff0c;zookeeper等。Spring integration组件有这三种服务的分布式锁实现&#xff0c;今天来看看用的比较多的redis和database实现方式。 …

ANTLR4规则解析生成器(三):遍历语法分析树

文章目录 1 词法分析2 语法分析3 遍历语法分析树3.1 Listener3.2 Visitor 4 总结 1 词法分析 词法分析就是对给定的字符串进行分割&#xff0c;提取出其中的单词。 在antlr4中&#xff0c;词法规则的名称的首字母需要大写&#xff0c;右侧必须是终结符&#xff0c;通常将词法…

Tomcat布署及优化

1.Tomcat简介 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器&#xff0c;Tomcat 属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试 JSP 程序的首选。一般来说&…

数据结构:队列 || oj(l两个队列实现栈)

[TOC](数据结构&#xff1a;队列 || oj(l两个队列实现栈)) 一、队列的概念 1.什么是队列&#xff1f; //先说一下&#xff0c;队列跟栈一样都是很重要的数据结构&#xff0c;重要的不是说这个数据结构怎么实现&#xff0c;重要的是结构的优势&#xff01; //栈&#xff1a;是…

上海亚商投顾:沪指终结月线6连阴 北向资金净买入超160亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日低开高走&#xff0c;沪指重新站上3000点&#xff0c;深成指、创业板指大涨超3%。半导体产业链全…

协议和序列化反序列化

“协议”和序列化反序列化 “协议”的概念&#xff1a; “协议”本身是一种约定俗成的东西&#xff0c;由通讯双方必须共同遵从的一组约定&#xff0c;因此我们一定要将这种约定用计算机语言表达出来&#xff0c;此时双方计算机才能识别约定的相关内容 我们把这个规矩叫做“…

仿真科普|CAE技术赋能无人机 低空经济蓄势起飞

喝一杯无人机送来的现磨热咖啡&#xff1b;在拥堵的早高峰打个“空中的士”上班&#xff1b;乘坐水陆两栖飞机来一场“陆海空”立体式观光……曾经只出现在科幻片里的5D城市魔幻场景&#xff0c;正逐渐走进现实。而推动上述场景实现的&#xff0c;就是近年来越来越热的“低空经…

包管理工具之npm也慌了?

起因 因为npm的种种问题,我很早就换成了pnpm和yarn(但是其实npm也在使用),已经很久没有关注npm的功能更新了。最近无意间进入Node18版本的安装目录,发现其除了常规的node,npm等默认安装了一个新的包corepack,这个就是今天我要分享的东西了。 注: 我因为18版本的node上…

Docker技术概论(3):Docker 中的基本概念

Docker技术概论&#xff08;3&#xff09; Docker 中的基本概念 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://…

MySQL 用户账号迁移

文章目录 前言1. 工具安装1.1 下载安装包1.2 编译安装 2. 用户迁移后记 前言 有一个典型的使用场景&#xff0c;就是 RDS 下云大多数都是通过 DTS 进行数据传输的&#xff0c;用户是不会同步到自建数据库的。需要运维人员在自建数据库重新创建用户&#xff0c;如果用户数量很多…