提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
一、信息打印
法一
print 'hello world'
这种打印方法是在消息窗口进行打印
法二
select 'hello world'
这种方法是在结果窗口进行打印
二、变量
T-SQL中变量分别为局部变量和全局变量
局部变量:(1)以@作为前缀(2)先声明,再赋值
declare @str varchar(10)--声明
set @str='hello'--赋值
print(@str)
关于赋值,除了set,也可以用select
declare @str varchar(10)--声明
select @str='i like sql'--赋值
print(@str)
set和select进行赋值的区别:
set:赋值给变量指定的值,比如上面的set @str=‘hello’
select:它也可以给变量赋指定值,另外它也可以从表里面查询一个值然后赋值给变量
select @a=字段名 from 表名
ps:select如果用于从表中查询出数据赋值给变量,一旦查询结果有多条,则取最后一条赋值给变量
全局变量:(1)以@@作为前缀(2)由系统进行定义和维护,只读
--@@ERROR:返回执行的上一个语句的错误号
--@@IDENTITY:返回最后插入的标识值
--@@MAX_CONNECTIONS:返回允许同时进行的最大用户连接数
--@@ROWCOUNT:返回受上一行语句影响的行数
--@@SERVERNAME:返回允许SQL Sever的本地服务器的名称
--@@SERVICENAME:返回SQL server正在其下运行的注册表项的名称
--@@TRANCOUNT:返回当前连接的活动事务数
--@@LOOK_TIMEOUT:返回当前会话的当前锁定超时设置(毫秒)
全局变量举例说明:
我们现在有两张银行常见的表:账户信息表、银行卡表
create table AccountInfo --账户信息表
(
AccountId int primary key identity(1,1),--账户编号
AccountCode varchar(20) not null,--身份证号码
AccountPhone varchar(20) not null,--电话号码
RealName varchar(20) not null,--真实姓名
OpenTime smalldatetime not null--开户时间
)
create table BankCard --银行卡
(
CardNo varchar(20) primary key ,--银行卡号
AccountId int not null,--账户编号(与账户信息表形成主外键关系)
CardPwd varchar(30) not null,--银行卡密码
CardMoney money not null,--银行卡余额
CardState int not null--状态:1正常、2挂失、3冻结、4注销
)
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('31425253343','13823131423','张三',GETDATE())
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState)
values('241532131',1,'123456',5000,1)
创建好这两个表后,我们向其中插入一些数据
然后我们会发现插入数据的时候产生了一些问题
我们这里因为之前表里面没有数据,所以理所当然的认为AccountId应该是1,
但是放在实际生活中,一个银行的银行账号有那么多,你怎么知道插入的时候编号是多少呢?
所以我们这里贸然插一个1是不理智的
正确的解法:用到我们上面说的@@IDENTITY:返回最后插入的标识值
我们用一个变量@Account来接收那个最后位置
然后insert的时候,用到@Account即可
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('31425253343','13823131423','张三',GETDATE())
declare @Account int
set @Account=@@IDENTITY
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState)
values('241532131',@Account,'123456',5000,1)
再多插入几个数据试试
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('31425253342','13823131423','李四',GETDATE())
declare @Account int
set @Account=@@IDENTITY
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState)
values('241532132',@Account,'123456',5000,1)
再查询BankCard表就会发现AccountId就自动变成2了
例题:仍用刚才的账号信息表和银行卡表
已知张三身份证:31425253343求出张三的银行卡号和余额
--写法1:不适用变量
select CardNo 卡号 ,CardMoney 余额 from BankCard
inner join AccountInfo on BankCard.AccountId=AccountInfo.AccountId
where AccountCode='31425253343'
查询结果:
--写法2:使用变量
declare @Account int
--把身份证编号存储到@Account里面
select @Account=(select AccountId from AccountInfo where AccountCode='31425253343')
--在BankCard表里面查询和@Account相同的AccountId
select CardNo 卡号,CardMoney 余额 from BankCard
where AccountId=@Account
查询结果:
三、go语句
1.等待go语句之前的代码执行完后才能执行后面的代码
举例说明:
比如我们下面有一段sql语句
我们原意是想创建一个aTest数据库,然后使用这个数据库,再在这个数据库里面建表
create database aTest
use aTest
create table A
(
a int
)
但是实际操作会发现系统给你报错了
你可能会说,哎呀你运行一下它才能创建嘛,运行之后use aTest就没有问题了啊
那我们试一下
事实上,即使运行了,也会报错。究竟是什么原因导致这样一个情况呢?
解释:我们原本的逻辑是建立在"建库一定发生在使用库之前"
如果在建库这个操作还没有完成,就执行了use aTest这样一个代码,就会报错了
那怎么保证“建库一定发生在使用库之前”呢?——使用go
create database aTest
go
use aTest
create table A
(
a int
)
使用go,可以保证go前面的语句一定在go后面的语句前面先完成。
2.批处理结束的一个标志
举例说明
我们下面三行代码是简单的声明一个变量a,然后两次给它进行赋值,运行也没有任何问题
declare @a int
set @a=1
set @a=2
我们试试在中间加入go,看看会发生什么
declare @a int
set @a=1
go
set @a=2
我们发现命名a声明过了,但是系统说68行的@a没有声明,这是为什么呢?
因为go是go前面部分代码的结束标志,由于go的存在,就相当于把go前面和go后面的代码隔离开了
四、运算符
T-SQL中使用的运算符分为7种
算术运算符:+ - * / %
--注:关于除法/,这个和C语言里面是一样的,
--整数除整数还是整数,浮点数/整数 得到浮点数,整数/浮点数 得到浮点数
逻辑运算符:AND、 OR、 LIKE、 BETWEEN、 IN、 EXISTS、 NOT、 ALL、 ANY
赋值运算符:=
字符串运算符:+
比较运算符:= > < >= <=
位运算:| & ^
复合运算符:+= -= /= %= *=
示例1:已知长方形的长和宽,求长方形的周长和面积
declare @c int =10--长
declare @k int =5--宽
declare @zc int
declare @mj int
set @zc=(@c+@k)*2
set @mj=@c*@k
--在java中字符串可以直接和整形相加(自动转换成字符串)
--但是sql中你需要把类型转换一下,要用到Convert函数
--用法:Convert(新的类型名,变量)
print('圆周长'+Convert(varchar(10),@zc))
print('圆面积'+Convert(varchar(10),@mj))
--也可以使用cast函数
print('圆周长'+cast(@zc as varchar(10)))
示例2:查询出银行卡状态为冻结(编号为3),并且余额超过10000的银行卡信息
select * from BankCard where CardState=3 and CardMoney>10000
示例3:查询银行卡状态为冻结或者余额等于0的银行卡信息
select * from BankCard where CardState =3 or CardMoney=0
示例4:查询出姓名中含有‘刘’的账号信息和银行卡信息
select * from AccountInfo
inner join BankCard on BankCard.AccountId=AccountInfo.AccountId
where RealName like'%刘%'
示例5:查询出余额在2000-5000之间的银行卡信息
select * from BankCard where CardMoney between 2000 and 5000
示例6:查询出银行卡状态为冻结(编号为3)或注销(编号为4)的银行卡信息
select * from BankCard where CardState in (3,4)
示例7:张三身份证:23142414142,现在张三来银行开户
试查询身份证在账户表中是否存在,不存在就进行开户开卡,存在则不开户直接开卡
declare @AccountId int
if EXISTS(select * from AccountInfo where AccountCode='23142414142')--存在此人
begin
select @AccountId=
(select AccountId from AccountInfo where AccountCode='23142414142')
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState)
values('3132342',@AccountId,'1321423',0,1)
end
else --不存在此人
begin
insert into AccountInfo(AccountCode,AccountPhone,RealName,OpenTime)
values('3142145231','13841823249','关羽',getdate())
set @AccountId=@@IDENTITY
insert into BankCard(CardNo,AccountId,CardPwd,CardMoney,CardState)
values('3132342',@AccountId,'1321423',0,1)
end
五、流程控制
1.选择分支结构
示例:某用户卡号为1234567,现在他进行取钱5000,
如果余额充足则进行取钱,提示“取钱成功”
否则提醒“余额不足”
declare @balance money
select @balance=
(select CardMoney from BankCard where CardNo='1234567')
if @balance >=5000
begin
update BankCard set CardMoney=CardMoney -5000
where CardNo='1234567'--必须加上卡号,不然就是所有人都被扣5000
print('取钱成功')
end
else
begin
print('余额不足')
end
2.循环结构(while)
示例1:循环打印1-10
declare @i int = 1
while @i<=10
begin
print(@i)
set @i+=1
end
示例2:打印九九乘法表
declare @i int = 1
while @i<=9
begin
declare @str varchar(150)=''
declare @j int =1
while @j<=@i
begin
set @str=@str+cast(@i as varchar(1))+'*'+cast(@j as varchar(1))+'='+cast(@i*@j as varchar(2))+' '
set @j+=1
end
set @i+=1
print(@str)
end