首页 > 数据库 > > SQL SERVER 高级语法之T-SQL
--print
复制代码
可以看到是打印在窗口中;
--select
复制代码
结果是打印在表格内的;select还可以用于从表里查询数据;
declare @str varchar(20)
set @str = '我爱数据库编程' --或者select @str = '我爱数据库编程'
print @str
复制代码
sql中的声明是以declare 开头
select @变量名 = 字段名 from 表名
复制代码
在赋值过程中,如果是表中查询的数据,如果记录只有一条,使用set和select都可以,但是习惯上使用select;
--@@ERROR: 返回执行的上一个语句的错误号
--@@IDENTITY:返回最后插入的标识值
--@@MAX_CONNECTIONS:返回允许同时进行的最大用户连接数
--@@ROWCOUNT:返回受上一语句影响的行数
--@@SERVERNAME:返回运行SQL Server的本地服务器的名称
--@@SERVICENAME:返回SQL Server 正在其下运行的注册表项的名称
--@@TRANCOUNT:返回当前连接的活动事务数
--@@LOCK_TIMEOUT:返回当前会话的当前锁定超时设置(毫秒)
复制代码
我们先执行了一个insert 操作,当保存了用户信息时,然后我们定义了一个AccountId的变量,它的加载方式是@@INENTITY,就是说获取的前面的insert的操作的主键id。拿到了此主键id,后续就进行了insert BankCard操作,就进行了开-户了。
-- 方案一: 连接查询
select CardNo 卡号,CardMoney 余额 from BankCard left join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where AccountCode = '420107199602034138'
-- 方案二: 使用变量
declare @AccountId int
select @AccountId = (select AccountId from AccountInfo where AccountCode = '420107199602034138')
select CardNo 卡号,CardMoney 余额 from BankCard where BankCard.AccountId = @AccountId
复制代码
在方案二中的查询中,@AccountId 的值的传入是通过后面的select 语句得到的,它是将查询出来的结果传给了AccountId;
图中的
create database DBTEST1建表操作还没有创建完成时,如果直接`use DBTEST1'则会抛异常报错。所以在这样的业务场景下,我们可以使用go,让之前的代码执行完毕后,再进行执行后续代码。
如果在go的上方,则声明的作用范围在上方,如果在两个go之间则就会在两个之间,它能够圈定一个作用范围,在go之后则无法再继续使用此变量了,因为go后面已经批处理结束了。
declare @c int =10
declare @k int =5
declare @zc int
declare @mj int
set @zc =(@c + @k )*2
set @mj = @c*@k
print '圆周长:'+ Convert(varchar(10),@zc)
print '圆面积' + Convert(varchar(10),@mj)
复制代码
打印结果为: 圆周长:30 圆面积50 ;这里的Convert是将@zc和@mj转成字符串,它的类型为varchar(10) 还可以使用cast函数,能够达到同样的效果,如图所示:
后续再讲他们之间的区别
select * from BankCard where CardState = 3 and CardMoney> 1000000
复制代码
这里3是冻结状态
select * from BankCard where CardState = 3 and CardMoney =0
复制代码
select * from AccountInfo inner join BankCard on BankCard.AccountId = AccountInfo.AccountId where RealName like '%刘%'
复制代码
select * from BankCard where CardMoney between 2000 and 5000
复制代码
select * from BankCard where CardState in(3,4)
复制代码
declare @AccountId int
if EXISTS(select * from AccountInfo where AccountCode = '420107199507104133') -- 存在此人
begin
select @AccountId = (select AccountId from AccountInfo where AccountCode = '420107199507104133') insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState) values('6225547858741264',@AccountId,'123456',0,1)
end
else -- 不存在
begin
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('420107199507104133','13656565656','关羽',getdate())
set @AccountId = @@IDENTITY
insert into BankCard (CardNo,AccountId,CardPwd,CardMoney,CardState)
values('6225547858741264',@AccountId,'123456',0,1)
end
复制代码
declare @AccountId int -- 账户编号
declare @CardCount int -- 卡数量
if EXISTS(select * from AccountInfo where AccountCode = '420107199507104133') -- 存在此人
begin
select @AccountId = (select AccountId from AccountInfo where AccountCode = '420107199507104133')
select @CardCount = (select count(*) from BankCard where AccountId = @AccountId)
if @CardCount <=2
begin
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState) values('6225547858741264',@AccountId,'123456',0,1)
end
else
begin
print '您名下的银行卡太多了,最多只能由3张银行卡'
end
end
else -- 不存在
begin
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('420107199507104133','13656565656','关羽',getdate())
set @AccountId = @@IDENTITY
insert into BankCard (CardNo,AccountId,CardPwd,CardMoney,CardState)
values('6225547858741264',@AccountId,'123456',0,1)
end
复制代码
if 3000 < All(select CardMoney from BankCard)
begin
print '所有的银行卡余额都超过了3000'
end
else
begin
print '不是所有的银行卡余额都超过了3000'
end
复制代码
if 30000000 < Any(select CardMoney from BankCard)
begin
print '有银行卡余额超过了3000'
end
else
begin
print '没有银行卡余额超过了3000'
end
复制代码
if xxx
begin
xxx
end
else
begin
xxx
end
复制代码
declare @banlance money
select @balance = (select CardMoney from BankCard where CardNo = '6225547854125656')
if @balance >= 5000
begin
update BankCard set CardMoney = CardMoney -5000
insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime)
values('6225547854125656',0,5000,GETDATE())
end
else
print '余额不足'
复制代码
select CardNo 卡号,AccountCode 身份证号,RealName 姓名,CardMoney 余额,
case
when CardMoney >= 300000 then 'VIP用户'
else '普通用户'
end 用户等级
case CardState
when 1 then '正常'
when 2 then '挂失'
when 3 then '冻结'
when 4 then '注销'
else '异常'
end
from BankCard
inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
复制代码
declare @int =1
while @i <=10
begin
print @i
set @i = @i +1
end
复制代码
declare @i int =1
while @i < 9
begin
declare @str varchar(1000) = ''
declare @j int =1
while @j <=@i
begin
set @str = @str + cast(@i as varchar(1)) + '*' + cast(@i as varchar(1)) + '=' + cast(@i*@j as varchar(2)) + char(9)
set @j = @j+1
end
set @i = @i +1
end
复制代码
特殊字符:char(9):制表符; char(10):换行符,print是自动换行
declare @gyBalance money
select @gyBalance = (select CardMoney from BankCard where CardNo = '6225547858741263')
select CardNo 卡号, AccountCode 身份证, RealName 姓名, CardMoney 余额 from BankCard left join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
where CardMoney > @gyBalance
复制代码
select CardNo 卡号,AccountCode 身份证, RealName 姓名,CardMoney 余额 from BankCard left join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
where CardMoney > (select CardMoney from BankCard where CardNo = '6225547858741263')
复制代码
select * from CardExchange where CardNo in (select CardNo from BankCard where CardMoney = (select MAX(CardMoney) from BankCard))
复制代码
select * from CardExchange where CardNo = (select top 1 CardNo from BankCard order by CardMoney desc)
复制代码
select CardNo 卡号,AccountCode 身份证,RealName 姓名,CardMoney 余额 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where CardNo in (select CardNo from CardExchange where MoneyOutBank > 0)
复制代码
select CardNo 卡号,AccountCode 身份证,RealName 姓名, CardMoney 余额 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where CardNo not in (select CardNo from CardExchange where MoneyInBank > 0 )
复制代码
if exists(select * from CardTransfer where CardNoIn = '6225547858741263' and CONVERT(VARCHAR(22),GETDATE(),23) = CONVERT(VARCHAR(22), TransferTime, 23))
begin
print '有收到转账'
end
else
begin
print '没有收到转账'
end
复制代码
select top 1 BankCard.CardNo 卡号,AccountCode 身份证, RealName 姓名, CardMoney 余额, Temp.myCount 交易次数 from BankCard
inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
inner join (select CardNo, count(*) myCount from CardExchange group by CardNo) Temp on BankCard.CardNo = Temp.CardNo
order by Temp.myCount desc
复制代码
select CardNo 卡号, AccountCode 身份证, RealName 姓名, CardMoney 余额 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
where CardNo not in (select CardNoOut from CardTransfer)
and CardNo not in (select CardNoIn from CardTransfer)
复制代码
declare @PageSize int = 5
declare @PageIndex int = 1
select top(@PageSize) * from Student where StuId not in (select top(@PageSize*(@PageIndex-1)) StuId from Student)
复制代码
当数据量大的时候,查询的效率并不高
declare @PageSize int = 4
declare @PageIndex int = 2
select * from (select ROW_NUMBER() over(order by StuId) RowId , * from Student) Temp
where RowId between(@PageIndex-1)* @PageSize+1 and @PageIndex * @PageSize
复制代码
begin transaction
declare @myError int = 0
update BankCard set CardMoney = CardMoney -6000 where CardNo = '6225125478544587' set @myError = @myError + @@ERROR
insert into CardExchange(CardNo, MoneyInBank, MoneyOutBank , ExchangeTime) values('6225125478544587',0,5000,GETDATE())
set @myError = @myError + @@ERROR
if @myError =0
begin
commit transaction
print '取款成功'
end
else
begin
rollback transaction
print '取款失败'
end
复制代码
@@ERROR 在异常时会返回一个错误int值,我们将这个错误值放入@myError,如果它的最终值大于0说明存在异常,则进行回滚,如果等于0 说明执行成功,则直接提交事务;
begin transaction
declare @myerr int =0
update BankCard set CardMoney = CardMoney + 1000 where CardNo = '6225547854125656' set @myerr = @myerr + @@ERROR
update BankCard set CardMoney = CardMoney -1000 where CardNo = '6225125478544587' set @myerr = @myerr + @@ERROR
insert into CardTransfer(CardNoOut, CardNoIn , TransferMoney,TransferTime) values('6225125478544587','6225547854125656',1000,GETDATE()) set @myerr = @myerr + @@ERROR
if @myerr = 0
begin
commit transaction
print '转账成功'
end
else
begin
rollback transaction
print '取款失败'
end
复制代码
CREATE [UNIQUE] [CLUSTERED | NONCLUSTE]
INDEX <index name> ON <table or view name>(<column name> [ASC|DESC][,...n])
复制代码
-- exp:创建一个非聚集索引
create nonclustered index indexAccount on AccountInfo(AccountCode)
-- 删除一个索引
drop index indexAccount on AccountInfo
复制代码
create unique nonclustered index index_code on AccountInfo(AccountCode)
复制代码
select * from sys.indexes where name = 'index_code'
复制代码
drop index index_code on AccountInfo
复制代码
select * from AccountInfo with(index = index_code) where AccountCode = '420107199507104133'
复制代码
create view CardAndAccount as select CardNo 卡号, AccountCode 身份证, RealName 姓名,CardMoney 余额 from BankCard left join AccountInfo on BankCard.AccountId= AccountInfo.AccountId
go
复制代码
select * from CardAndAccount
复制代码
drop view View_Account_Card
复制代码
-- 创建游标(scroll:滚动游标,没有scroll,只进)
declare mycur cursor scroll for select MemberAccount from Member # mycur是游标名称, cursor标识它是一个游标,scroll是类型表示它是一个滚动游标 MemberAccount表示游标的值为Member表中的MemberAccount字段。
-- 游标打开
open mycur
-- 提取某行数据
fetch first from mycur --提取第一行数据
fetch last from mycur -- 提取最后一行
fetch absolute 2 from mycur -- 提取第二行
fetch relative 2 from mycur -- 当前行下移
fetch next from mycur -- 下移一行
fetch prior from mycur -- 上移一行
-- 提取游标数据存入变量,进行查询所有列数据
declare @acc varchar(20)
fetch absolute 2 from mycur into @acc # 绝对游标第二行数据存入@acc变量,然后下方再进行查询
select * from Member where MemberAccount = @acc
-- 遍历游标
declare @acc varchar(20)
fetch absolute 1 from mycur into @acc
-- @@fetch_status: 0提取成功, -1 表示失败, -2 不存在
while @@fetch_status = 0
begin
print '提取成功' + @acc
fetch next from mycur into @acc
end
-- 上面的遍历是while进行持续判端,然后begin方法中一直下移游标,然后实现了遍历操作;
-- 利用游标进行数据的修改和删除
select * from Member fetch absolute 2 from mycur update Member set MemberPwd = '654321' where current of mycur
fetch absolute 2 from mycur delete from Member where current of mycur
-- 关闭游标
close mycur
-- 删除游标
deallocate mycur
-- 创建指向某行多列的游标,循环显示多列数据
declare mycur cursor scroll for select MemberAccount, MemberPwd,MemberNickName from Member # 其中MemberAccount, MemberPwd,MemberNickName 均为Member表中字段,我们使用时根据实际来确定;
-- 上面定义好游标后,我们下面开始进行遍历操作:
declare @acc varchar(20)
declare @pwd varchar(20)
declare @nickname varchar(20)
fetch absolute 1 from mycur into @acc, @pwd, @nickname
-- @@fetch_status: 0 提取成功 , -1 失败 , -2 不存在
while @@fetch_status = 0
begin
print '用户名:'+@acc + ',密码:'+@pwd +',昵称:'+@nickname fetch next from mycur into @acc, @pwd,@nickname
end
-- 关闭游标
close mycur
-- 删除游标
deallocate mycur
复制代码
游标关闭后可以再打开,但是删除后如果需要再使用则必须重新建了。游标类似于指向数据的指针,所以灵活性非常高。
drop function GetSumMoney
create function GetSumMoney() returns money
as
begin
declare @sum money
select @sum= (select SUM(CardMoney) from BankCard)
return @sum
end
-- 函数调用
select dbo.GetSumMoney()
复制代码
上面函数没有参数,下面介绍有参数函数的定义及使用
create function GetRealNameById(@accid int) returns varcahr(30)
as
begin
declare @name varchar(30)
select @name = (select RealName from AccountInfo where AccountId = @accid) return @name
end
select dbo.GetRealNameById(2)
复制代码
create function GetRecordByTime(@start varcahr(30),@end varchar(30)) returns @result table (
RealName varchar(20), --真实姓名
CardNo varchar(30), -- 银行卡号(与银行卡表形成主外键关系)
MoneyInBank money, -- 存钱金额
MoneyOutBank money, -- 取钱金额
ExchangeTime smalldatetime -- 交易时间
)
as
begin
insert into @result
select RealName 姓名,CardExchange.CardNo 卡号, MoneyInBank 存钱金额, MoneyOutBank 取钱金额,ExchangeTime 交易时间 from CardExchange
inner join BankCard on CardExchange.CardNo = BankCard.CardNo
inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where ExchangeTime between @start+ ' 00:00:00' and @end + ' 23:59:59'
return
end
-- 函数调用使用
select * from GetRecordByTime('2020-01-01', '2020-12-12')
复制代码
drop function GetRecordByTime
create function GetRecordByTime(@start varcahr(30),@end varchar(30))
return table
as
return
select RealName 姓名,CardExchange.CardNo 卡号, MoneyInBank 存钱金额, MoneyOutBank 取钱金额,ExchangeTime 交易时间 from CardExchange
inner join BankCard on CardExchange.CardNo = BankCard.CardNo
inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId where ExchangeTime between @start+ ' 00:00:00' and @end + ' 23:59:59'
go
-- 函数调用使用
select * from GetRecordByTime('2020-01-01', '2020-12-12')
复制代码
select CardNo 卡号,AccountCode 身份证,RealName 姓名, CardMoney 余额,
case
when CardMoney < 300000 then '普通用户'
else 'VIP用户'
end 用户等级,
case
CardState
when 1 then '正常'
when 2 then '挂失'
when 3 then '冻结'
when 4 then '注销'
else '异常'
end 卡状态
from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
复制代码
-- 创建用户等级函数
create function GetGrade(@cardmoney money) returns varchar(30)
as
begin
declare @result varchar(30)
if @cardmoney >= 300000
set @result = 'VIP用户'
else
set @result = '普通用户'
return @result
end
-- 求银行卡状态的函数:
create function GetState(@state int) returns varchar(30)
as
begin
declare @result varchar(30)
if @state =1
set @result = '正常'
else if @state = 2
set @result = '挂失'
else if @state = 3
set @result = '冻结'
else if @state = 4
set @result = '注销'
else
set @result = '异常'
return @result
end
-- 查询的时候直接使用函数,查询语句如下
select CardNo 卡号, AccountCode 身份证, RealName 姓名, CardMoney 余额, dbo.GetGrade(CardMoney) 用户等级, dbo.GetState(CardState) 银行卡状态 from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
复制代码
-- 方案一,直接查询:
select *,year(GETDATE()) - year(empBirth) 年龄 from Emp
-- 方案二,使用函数查询:
create function GetAge(@birth smalldatetime) returns int
as
begin
declare @age int
set @age = year(GETDATE()) -year(@birth)
if month(getdate()) < month(@birth)
set @age = @age -1
if month(getdate()) = month(@birth) and day(getdate()) <day(@birth)
set @age = @age -1
return @age
end
select *,dbo.GetAge(empBirth) 年龄 from Emp
复制代码
使用函数能够更加精确,也更加灵活,同时可以多处复用,我们可以在需要以上优势的地方使用它;
触发器概念:触发器是一种特殊类型的存储过程,它不同于我们下一节要介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。
什么是触发器?触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是对某一个表进行操作。诸如:update、insert、delete这些操作的时候,系统会自动调用执行该表上对应的触发器。SQL Server2005 中触发器可以分为两类:DML触发器和DDL触发器,其中DDL触发器它们会影响多种数据定义语言语句而激发,这些语句有create、alter、drop语句。
触发器分类:
两者区别在于after触发器要求只有执行某一操作insert、update、delete之后触发器才被触发,且只能定义在表上。而instead of 触发器表示并不执行其定义的操作(insert、update、delete)而仅是执行触发器本身。既可以在表上定义instead of 触发器,也可以在视图上定义。
触发器的表:触发器有两个特殊的表:插入表(instered表)和删除表(deleted表)。这两张是逻辑表也是虚表。有系统在内存中创建两张表,不会存储在数据库中。而且两张表都是只读的,只能读取数据而不能修改数据。这两张表的结果总是与被改动触发器应用的表的结构相同。当触发器完成工作后,这两张表就会被删除。inserted表的数据是插入或是修改后的数据,而deleted表的数据是更新前的或是删除的数据。
create trigger tri_InsertPeople on People after insert
as
if exists(select * from Department where DepartmentId = (select DepartmentId from inserted))
begin
insert into Department(DepartmentId, DepartmentName)
values((select DepartmentId from inseted),'新部门')
end
go
-- 测试触发器
insert into People(DepartmentId, PeopleName, PeopleSex,PeoplePhone) values('003','赵云','男','13698547125')
insert into People(DepartmentId,PeopleName,PeopleSex,PeoplePhone) values('002','张飞','男','13698547125')
复制代码
create trigger tri_DeleteDept on Department after delete
as
delete from People where DepartmentId = (select DepartmentId from deleted)
go
select * from Department
select * from People
-- 测试触发器
delete from Department where DepartmentId = '006'
复制代码
相当于实现了一个级联删除的操作;
drop trigger tri_DeleteDept
create trigger tri_DeleteDept on Department after delete
as
if not exists(select * from People where DepartmentId = (select DepartmentId from deleted))
delete from Department where DepartmentId = (select DepartmentId from deleted)
go
-- 测试触发器
delete from Department where DepartmentId = '001'
复制代码
create trigger tri_UpdateDept on Department after update
as
update People set DepartmentId = (select DepartmentId from inserted)
where DepartmentId = (select DepartmentId from deleted)
go
update Department set DepartmentId = '005' where DepartmentId = '001'
复制代码
注意:使用触发器需要注意一点,一个功能点根据A删除触发B删除、另外一个功能点根据B删除触发C删除、以此类推,本意操作A只想连带删除B,但可能导致其他的触发器也同时生效,导致全部均被删除;
函数一般是在sql中引用,而存储过程是可以直接被外部调用,比如java或者C# 语言可以直接调用存储过程语句;
exec sp_databases; --查看数据库
exec sp_tables; --查看表
exec sp_columns student;--查看列
exec sp_helpIndex student;--查看索引
exec sp_helpConstraint student;--约束
exec sp_stored_procedures;
exec sp_helptext 'sp_stored_procedures';--查看存储过程创建、定义语句
exec sp_rename student, stuInfo;--修改表、索引、列的名称
exec sp_renamedb myTempDB, myDB;--更改数据库名称
exec sp_defaultdb 'master', 'myDB';--更改登录名的默认数据库
exec sp_helpdb;--数据库帮助,查询数据库信息
exec sp_helpdb master;
复制代码
--表重命名
exec sp_rename 'stu', 'stud';
select * from stud;
--列重命名
exec sp_rename 'stud.name', 'sName', 'column';
exec sp_help 'stud';
--重命名索引
exec sp_rename N'student.idx_cid', N'idx_cidd', N'index';
exec sp_help 'student';
--查询所有存储过程
select * from sys.objects where type = 'P';
select * from sys.objects where type_desc like '%pro%' and name like 'sp%';
复制代码
create proc | procedure pro_name
[{@参数数据类型} [=默认值] [output],
{@参数数据类型} [=默认值] [output],
...
]
as
SQL_statement
复制代码
-- 定义存储过程实现查询出账户余额最低的银行卡账户信息,显示银行卡号,姓名,账户余额
drop proc proc_MinMoneyCard
create proc proc_MinMoneyCard
as
select top 1 CardNo,RealName,CardMoney from BankCard inner join AccountInfo on BankCard.AccountId = AccountInfo.AccountId
order by CardMoney
go
exec proc_MinMoneyCard
select * from BankCard
-- 方案二:(余额最低,多个人并列,都可以查出来)
create proc proc_MinMoneyCard
as
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
复制代码
--模拟银行卡取钱操作,传入银行卡号,存钱金额,实现存钱操作
create proc proc_Cunqian
@CardNo varchar(30)
@money money
as
update BankCard set CardMoney = CardMoney + @money where CardNo = @CardNo
insert into CardExchange(CardNo, MoneyInBank,MoneyOutBank,ExchangeTime)
values(@CardNo,@money,0,getdate())
go
select * from BankCard
select * from CardExchange
exec proc_Cunqian '6225547858741263',1000
复制代码
-- 模拟银行卡取钱操作,传入银行卡号,取钱金额,实现取钱操作,
-- 取钱成功,返回1, 取钱失败返回-1
create proc proc_Quqian
@CardNo varchar(30),
@money money
as
update BankCard set CardMoney = CardMoney - @money
where CardNo = @CardNo
if @@ERROR <> 0
return -1
insert into CardExchange(CardNo,MoneyInBank,MoneyOutBank,ExchangeTime) values(@CardNo,0,@money,getdate())
return 1
go
declare @returnValue int
exec @returnValue = proc_Quqian '6225125478544587',100
select @returnValue
~~~
复制代码
-- 查询出某时间段的银行存取款信息以及存款总金额,取款总金额,
-- 传入开始时间,结束时间,显示存取款交易信息的同时,返回存款总金额,取款总金额。
create proc proc_selectExchange
@start varchar(20), --开始时间
@end varchar(20), --结束时间
@sumIn money output, --存款总金额
@sumOut money output -- 取款总金额
as
select @sumIn= (select sum (MoneyInBank) from CardExchange where ExchangeTime between @start + ' 00:00:00' and @end + ' 23:59:59')
select @sumOut = (select sum(MoneyOutBank) from CardExchange where ExchangeTime between @start + ' 00:00:00' and @end + ' 23:59:59')
select * from CardExchange where ExchangeTime between @start + ' 00:00:00' and @end + ' 23:59:59'
go
declare @sumIn money
declare @sumOut money
exec proc_selectExChange '2020-1-1','2020-12-11',@sumIn output,@sumOut output
select @sumIn
select @sumOut
复制代码
-- 密码升级,传入用户名和密码,如果用户名密码正确,并且密码长度<8 ,自动升级成8位密码
select * from BankCard
select floor(rand()*10)
create proc procPwdUpgrade
@CardNo nvarchar(20), --卡号
@pwd nvarchar(20) output --卡号
as
if not exists(select * from BankCard where CardNo = @CardNo and CardPwd = @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 BankCard set CardPwd = @pwd where CardNo = @CardNo
end
go
declare @pwd nvarchar(20) = '123456'
exec procPwdUpgrade '6225125478544587',@pwd output
select @pwd
复制代码
@pwd nvarchar(20) output 说明它既可以当做输入也可以作为输出;
看完啦~ 博主码字不易,觉得有用可以收藏点赞,感谢您的观看,我们一起加油ヾ(◍°∇°◍)ノ゙
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69999831/viewspace-3150945/ ,如需转载,请注明出处,否则将追究法律责任。