iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >SQL Server中函数、存储过程与触发器怎么用
  • 638
分享到

SQL Server中函数、存储过程与触发器怎么用

2023-06-29 23:06:13 638人浏览 泡泡鱼
摘要

这篇文章主要讲解了“sql Server中函数、存储过程与触发器怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL Server中函数、存储过程与触发器怎么用”吧

这篇文章主要讲解了“sql Server中函数、存储过程与触发器怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SQL Server中函数、存储过程与触发器怎么用”吧!

一、函数

函数分为(1)系统函数,(2)自定义函数。

其中自定义函数又可以分为(1)标量值函数(返回单个值),(2)表值函数(返回查询结果)

本文主要介绍自定义函数的使用。

(1)编写一个函数求该银行的金额总和

create function GetSumCardMoney()returns money asbegindeclare @AllMOney moneyselect @AllMOney = (select SUM(CardMoney) from BankCard)return @AllMOneyend

函数调用

select dbo.GetSumCardMoney()

上述函数没有参数,下面介绍有参数的函数的定义及使用

(2)传入账户编号,返回账户真实姓名

create function GetNameById(@AccountId int)returns  varchar(20)asbegindeclare @RealName varchar(20)select @RealName = (select RealName from AccountInfo where AccountId = @AccountId)return @RealNameend

函数调用

print dbo.GetNameById(2)

(3)传递开始时间和结束时间,返回交易记录(存钱取钱),交易记录中包含 真实姓名,卡号,存钱金额,取钱金额,交易时间。

方案一(逻辑复杂,函数内容除了返回结果的sql语句还有其他内容,例如定义变量等):

create function GetExchangeByTime(@StartTime varchar(30),@EndTime varchar(30))returns @ExchangeTable table(RealName varchar(30),  --真实姓名CardNo varchar(30),    --卡号MoneyInBank money,     --存钱金额MoneyOutBank money,    --取钱金额ExchangeTime smalldatetime  --交易时间)asbegininsert into @ExchangeTableselect AccountInfo.RealName,CardExchange.CardNo,CardExchange.MoneyInBank,CardExchange.MoneyOutBank,CardExchange.ExchangeTime from CardExchangeleft join BankCard on CardExchange.CardNo = BankCard.CardNoleft join AccountInfo on BankCard.AccountId = AccountInfo.AccountIdwhere CardExchange.ExchangeTime between @StartTime+' 00:00:00' and @EndTime+' 23:59:59'returnend

函数调用

select * from GetExchangeByTime('2018-6-1','2018-7-1')

方案二(逻辑简单,函数内容直接是一条sql查询语句):

create function GetExchangeByTime(@StartTime varchar(30),@EndTime varchar(30))returns tableasreturnselect AccountInfo.RealName,CardExchange.CardNo,CardExchange.MoneyInBank,CardExchange.MoneyOutBank,CardExchange.ExchangeTime from CardExchangeleft join BankCard on CardExchange.CardNo = BankCard.CardNoleft join AccountInfo on BankCard.AccountId = AccountInfo.AccountIdwhere CardExchange.ExchangeTime between @StartTime+' 00:00:00' and @EndTime+' 23:59:59'Go

函数调用:

select * from GetExchangeByTime('2018-6-19','2018-6-19')

(4)查询银行卡信息,将银行卡状态1,2,3,4分别转换为汉字“正常,挂失,冻结,注销”,根据银行卡余额显示银行卡等级 30万以下为“普通用户”,30万及以上为"VIP用户",分别显示卡号,身份证,姓名,余额,用户等级,银行卡状态。

方案一:直接在sql语句中使用case when

select * from AccountInfoselect * from BankCardselect CardNo 卡号,AccountCode 身份证,RealName 姓名,CardMoney 余额,casewhen CardMoney < 300000 then '普通用户'else 'VIP用户' end 用户等级,casewhen CardState = 1 then '正常'when CardState = 2 then '挂失'when CardState = 3 then '冻结'when CardState = 4 then '注销'else '异常'end 卡状态from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId

方案二:将等级和状态用函数实现

create function GetGradeByMoney(@myMoney int)returns varchar(10)asbegindeclare @result varchar(10)if @myMoney < 3000 set @result = '普通用户'elseset @result = 'VIP用户'return @resultendgocreate function GetStatusByNumber(@myNum int)returns varchar(10)asbegindeclare @result varchar(10)if @myNum = 1set @result = '正常'else if @myNum = 2set @result = '挂失'else if @myNum = 3set @result = '冻结'else if @myNum = 4set @result = '注销'elseset @result = '异常'return @resultendgo

函数调用实现查询功能

select CardNo 卡号,AccountCode 身份证,RealName 姓名,CardMoney 余额,dbo.GetGradeByMoney(CardMoney) 账户等级,dbo.GetStatusByNumber(CardState) 卡状态from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId

(5)编写函数,根据出生日期求年龄,年龄求实岁,例如:

生日为2000-5-5,当前为2018-5-4,年龄为17岁
生日为2000-5-5,当前为2018-5-6,年龄为18岁

测试数据如下:

create table Emp(EmpId int primary key identity(1,2), --自动编号empName varchar(20), --姓名empSex varchar(4),   --性别empBirth smalldatetime --生日)insert into Emp(empName,empSex,empBirth) values('刘备','男','2008-5-8')insert into Emp(empName,empSex,empBirth) values('关羽','男','1998-10-10')insert into Emp(empName,empSex,empBirth) values('张飞','男','1999-7-5')insert into Emp(empName,empSex,empBirth) values('赵云','男','2003-12-12')insert into Emp(empName,empSex,empBirth) values('马超','男','2003-1-5')insert into Emp(empName,empSex,empBirth) values('黄忠','男','1988-8-4')insert into Emp(empName,empSex,empBirth) values('魏延','男','1998-5-2')insert into Emp(empName,empSex,empBirth) values('简雍','男','1992-2-20')insert into Emp(empName,empSex,empBirth) values('诸葛亮','男','1993-3-1')insert into Emp(empName,empSex,empBirth) values('徐庶','男','1994-8-5')

函数定义:

create function GetAgeByBirth(@birth smalldatetime)returns intasbegindeclare @age intset @age = year(getdate()) - year(@birth)if month(getdate()) < month(@birth)set @age = @age - 1if month(getdate()) = month(@birth) and day(getdate()) < day(@birth)set @age = @age -1return @ageend

函数调用实现查询

select *,dbo.GetAgeByBirth(empBirth) 年龄 from Emp

二、触发器

触发器分类:(1) “Instead of”触发器(2)“After”触发器
“Instead of”触发器:在执行操作之前被执行
“After”触发器:在执行操作之后被执行

触发器中后面的案例中需要用到的表及测试数据如下:

--部门create table Department(DepartmentId varchar(10) primary key , --主键,自动增长DepartmentName nvarchar(50), --部门名称)--人员信息create table People(PeopleId int primary key identity(1,1), --主键,自动增长DepartmentId varchar(10), --部门编号,外键,与部门表关联PeopleName nvarchar(20), --人员姓名PeopleSex nvarchar(2), --人员性别PeoplePhone nvarchar(20), --电话,联系方式)insert into Department(DepartmentId,DepartmentName)values('001','总经办')insert into Department(DepartmentId,DepartmentName)values('002','市场部')insert into Department(DepartmentId,DepartmentName)values('003','人事部')insert into Department(DepartmentId,DepartmentName)values('004','财务部')insert into Department(DepartmentId,DepartmentName)values('005','软件部')insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone)values('001','刘备','男','13558785478')insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone)values('001','关羽','男','13558788785')insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone)values('002','张飞','男','13698547125')

(1)假设有部门表和员工表,在添加员工的时候,该员工的部门编号如果在部门表中找不到,则自动添加部门信息,部门名称为"新部门"。

编写触发器:

create trigger tri_InsertPeople on Peopleafter insertasif not exists(select * from Department where DepartmentId = (select DepartmentId from inserted))insert into Department(DepartmentId,DepartmentName)values((select DepartmentId from inserted),'新部门')go

测试触发器:

insert People(DepartmentId,PeopleName,PeopleSex,PeoplePhone)values('009','赵云','男','13854587456')

我们会发现,当插入赵云这个员工的时候会自动向部门表中添加数据。

(2)触发器实现,删除一个部门的时候将部门下所有员工全部删除。

编写触发器:

create trigger tri_DeleteDept on Departmentafter deleteasdelete from People where People.DepartmentId = (select DepartmentId from deleted)go

测试触发器:

delete Department where DepartmentId = '001'

我们会发现当我们删除此部门的时候,同时会删除该部门下的所有员工

(3)创建一个触发器,删除一个部门的时候判断该部门下是否有员工,有则不删除,没有则删除。

编写触发器:

drop trigger tri_DeleteDept--删除掉之前的触发器,因为当前触发器也叫这个名字create trigger tri_DeleteDept on DepartmentInstead of deleteas  if not exists(select * from People where DepartmentId = (select DepartmentId from deleted))  begindelete from Department where DepartmentId = (select DepartmentId from deleted)  endgo

测试触发器:

delete Department where DepartmentId = '001'delete Department where DepartmentId = '002'delete Department where DepartmentId = '003'

我们会发现,当部门下没有员工的部门信息可以成功删除,而部门下有员工的部门并没有被删除。

(4)修改一个部门编号之后,将该部门下所有员工的部门编号同步进行修改

编写触发器:

create trigger tri_UpdateDept on Departmentafter updateasupdate People set DepartmentId = (select DepartmentId from inserted)where DepartmentId = (select DepartmentId from deleted)go

测试触发器:

update Department set DepartmentId = 'zjb001' where DepartmentId='001'

我们会发现不但部门信息表中的部门编号进行了修改,员工信息表中部门编号为001的信息也被一起修改了。

三、存储过程

存储过程(Procedure)是SQL语句和流程控制语句的预编译集合

(1)没有输入参数,没有输出参数的存储过程。

定义存储过程实现查询出账户余额最低的银行卡账户信息,显示银行卡号,姓名,账户余额

--方案一create proc proc_MinMoneyCardas    select top 1 CardNo 银行卡号,RealName 姓名,CardMoney 余额    from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId    order by CardMoney ascgo--方案二:(余额最低,有多个人则显示结果是多个)create proc proc_MinMoneyCardas    select CardNo 银行卡号,RealName 姓名,CardMoney 余额    from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId    where CardMoney=(select MIN(CardMoney) from BankCard)go

执行存储过程:

exec proc_MinMoneyCard

(2)有输入参数,没有输出参数的存储过程

模拟银行卡存钱操作,传入银行卡号,存钱金额,实现存钱操作

create proc proc_CunQian@CardNo varchar(30),@MoneyInBank moneyas    update BankCard set CardMoney = CardMoney + @MoneyInBank where CardNo = @CardNo    insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)    values(@CardNo,@MoneyInBank,0,GETDATE())--go

执行存储过程:

exec proc_CunQian '6225125478544587',3000

(3)有输入参数,没有输出参数,但是有返回值的存储过程(返回值必须整数)。

模拟银行卡取钱操作,传入银行卡号,取钱金额,实现取钱操作,取钱成功,返回1,取钱失败返回-1

create proc proc_QuQian@CardNo varchar(30),@MoneyOutBank moneyas    update BankCard set CardMoney = CardMoney - @MoneyOutBank where CardNo = @CardNo    if @@ERROR <> 0        return -1    insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)    values(@CardNo,0,@MoneyOutBank,GETDATE())    return 1go

执行存储过程:

declare @returnValue intexec @returnValue = proc_QuQian '662018092100000002',1000000print @returnValue

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

查询出某时间段的银行存取款信息以及存款总金额,取款总金额,传入开始时间,结束时间,显示存取款交易信息的同时,返回存款总金额,取款总金额。

create proc proc_SelectExchange    @startTime varchar(20),  --开始时间    @endTime varchar(20),    --结束时间    @SumIn money output,     --存款总金额    @SumOut money output    --取款总金额asselect @SumIn = (select SUM(MoneyInBank) from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59')select @SumOut = (select SUM(MoneyOutBank) from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59')select * from CardExchange where ExchangeTime between @startTime+' 00:00:00' and @endTime+' 23:59:59'go

执行存储过程:

declare @SumIn money     --存款总金额declare @SumOut money   --取款总金额exec proc_SelectExchange '2018-1-1','2018-12-31',@SumIn output,@SumOut outputselect @SumInselect @SumOut

(5)具有同时输入输出参数的存储过程

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

--有输入输出参数(密码作为输入参数也作为输出参数)--密码升级,传入用户名和密码,如果用户名密码正确,并且密码长度<8,自动升级成8位密码select FLOOR(RAND()*10) --0-9之间随机数create proc procPwdUpgrade@cardno nvarchar(20),@pwd nvarchar(20) outputasif not exists(select * from BankCard where CardNo=@cardno and CardPwd=@pwd)set @pwd = ''elsebeginif len(@pwd) < 8begindeclare @len int = 8- len(@pwd)declare @i int = 1while @i <= @lenbeginset @pwd = @pwd + cast(FLOOR(RAND()*10) as varchar(1))set @i = @i+1endupdate BankCard set CardPwd = @pwd where CardNo=@cardnoendendgodeclare @pwd nvarchar(20) = '123456'exec procPwdUpgrade '6225547854125656',@pwd outputselect @pwd

感谢各位的阅读,以上就是“SQL Server中函数、存储过程与触发器怎么用”的内容了,经过本文的学习后,相信大家对SQL Server中函数、存储过程与触发器怎么用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: SQL Server中函数、存储过程与触发器怎么用

本文链接: https://www.lsjlt.com/news/326670.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c语言怎么保证除完还是小数
    在 c 语言中,整数除法只能得到整数结果,要得到小数结果,需将操作数显式转换为浮点数:将一个操作数转换为浮点数,如 float result = num1 / (float)num2;将...
    99+
    2024-05-14
    c语言
  • c语言怎么让结尾不输出空行字符
    要阻止 c 语言程序结尾输出空行字符,可以使用以下方法:将 main 函数的返回值类型改为 void;在 main 函数中显式返回 0;调用 fflush(stdout) 函数刷新标准输...
    99+
    2024-05-14
    c语言
  • c语言怎么让结尾不输出空行数据
    在 c 语言中,可通过以下方法抑制 printf() 函数在程序结束时打印末尾空行:调用 fflush() 函数刷新缓冲区,立即输出所有数据;使用 setvbuf() 函数关闭缓冲,使数...
    99+
    2024-05-14
    c语言
  • c语言怎么让结尾无空行
    在 c 中去除结尾空行的方法:使用 fflush() 刷新缓冲区。使用 setvbuf() 将缓冲模式设置为 _ionbf。使用 printf 宏,它默认禁用缓冲。 如何在 C 语言中...
    99+
    2024-05-14
    c语言
  • c语言怎么输入实数赋值
    c语言中使用scanf()函数输入实数并赋值给变量:格式:scanf("%lf", &amp;variable);%lf是格式说明符,指定输入双精度浮点数;&...
    99+
    2024-05-14
    c语言
  • c语言怎么表达负数
    c语言中,负数以减号 (-) 表示,放在数字或变量前。负数运算规则包括:绝对值取正数;加正数或负数,结果取决于绝对值大小;乘或除以正数或负数,结果由符号奇偶性决定。负数的平方始终为正数,...
    99+
    2024-05-14
    c语言
  • c语言怎么输入Jac数列
    jacobi 数列的输入和生成方法分别有:1. 直接输入法:使用 scanf() 函数逐项输入数列。2. 递归生成法:使用递归公式生成数列,需初始化数列的前两项,然后按公式生成后续项。 ...
    99+
    2024-05-14
    c语言
  • c语言怎么把数组变成字符串
    在 c 语言中,将数组转换成字符串的方法包括:使用 sprintf() 将数组格式化为字符串。使用 strcpy() 将数组复制到字符串。使用 strncpy() 将指定长度的数组复制到...
    99+
    2024-05-14
    c语言
  • c语言怎么批量注释
    批量注释 c 语言代码的方法有:使用代码编辑器:使用快捷键或菜单命令自动添加 // 注释符号。使用注释工具:如 doxygen 和 cutter,批量添加行注释、块注释和文档注释。使用脚...
    99+
    2024-05-14
    python sublime c语言
  • c语言怎么把选中的全部注释
    c语言中注释选中内容可通过以下步骤实现:选中要注释的代码。根据使用的编辑器或ide,执行注释操作,例如在visual studio中右键单击并选择“注释所选内容”。添加注释内容。保存更改...
    99+
    2024-05-14
    sublime c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作