sql存储过程语法详解

sql存储过程语法详解一、定义变量使用关键字declare申明变量:declare@变量名变量类型/*简单赋值*/declare@aintset@a=5print@a/*select赋值*/declare@bnvarchar(10)select@b=stu_namefromdbo.studentwherestu_id=6print@b/…

大家好,又见面了,我是你们的朋友全栈君。

一、定义变量

使用关键字declare申明变量:

declare @变量名 变量类型

/*简单赋值*/

 declare @a int
 set     @a=5
 print   @a

/*select赋值*/

declare @b nvarchar(10)
select @b= stu_name from dbo.student where stu_id=6
print @b

/*update赋值*/

declare @c  nvarchar(10)
update dbo.student set @c=stu_name where stu_id=5
print @c

运行结果:
这里写图片描述
ps:使用set赋值时,等式右边不可以用函数表达式。

二、临时表、表变量

临时表:
临时表的创建是在Tempdb中,在一个数据库连接结束后或者由SQL命令DROP掉,才会消失,否则就会一直存在。临时表在创建的时候都会产生SQL Server的系统日志。在Tempdb中体现,在内存中分配,它们也支持物理的磁盘,但用户在指定的磁盘里看不到文件。

/*创建本地临时表#*/
create table #tablename()

/*创建全局临时表##*/
create table ##tablename()
/*创建一个临时表#student*/
create table #student( id int, username nvarchar(20), sex nvarchar(2), age int ) /*向临时表中插入一条数据*/ insert into #student values(1,'Susan','女',18) /*从student表查询数据,填充至新生成的临时表*/ 1.select * into #student2 from student where stu_age>30 2.insert into #student select * from student where stu_age>30 

这里写图片描述

由于手误,执行了两次,表中出现了重复项,且每一列值都相同
怎么删除完全重复的项的呢?

delete T from (select ROW_NUMBER() over(partition by username order by id) as rownumber, * from #student) T WHERE T.rownumber>1

语法:ROW_NUMBER( ) OVER ( PARTITION BY 列1 ORDER BY 列2 )
根据COLUMN分组,在分组内部根据 COLUMN排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)
函数“Row_Number”必须有 OVER 子句。OVER 子句必须有包含 ORDER BY

这里写图片描述

/*查询并联合两临时表*/
select * from #student where id >2 union select * from #student2 /*删除两临时表*/ drop table #student drop table #student2
/*添加一列为int型自增长列*/
alter table #student add innerid int not null identity(1,1)

ps:identity(1,1)自增列,从1开始递增,每次加1
这里写图片描述

/*增加一列,默认填充全球唯一标识*/
alter table #student add myid uniqueidentifier not null default(newid())

表变量:
表变量是变量的一种,表变量也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户连接中才可以访问。全局的表变量的名称都是以“@@”为前缀,一般都是系统的全局变量。

declare @local_variable table()

declare @t table(
  id int not null,
  msg nvarchar(50) not null
)

insert into @t values(1,'1')
insert into @t values(2,'2')
select * from @t

临时表与表变量的区别:
这里写图片描述

ps:
非聚集索引:数据行的逻辑顺序与磁盘上行的物理存储顺序不同,一个表中可以拥有多个非聚集索引。
聚集索引:与非聚集索引相反。
更多关于聚集索引与非聚集索引:
1.https://www.cnblogs.com/s-b-b/p/8334593.html
2.https://www.cnblogs.com/Jessy/p/3543063.html
更多关于表变量和临时表:
1.https://www.jb51.net/article/23952.htm
2.https://www.cnblogs.com/xinaixia/p/5821548.html

三、循环

while循环计算1到100的和:

declare @d int
declare @sum int
set @d=1
set @sum=0
while @d<100
begin
  set @d+=1
  set @sum+=@d
end
print @sum

这里写图片描述

四、条件语句

if-else

if1+1=2begin
  printf("对"end
else
begin
  print("错"end

when -then

declare @today int
declare @week nvarchar(3)
set @week=case
set@today=1
   when @today=1 then '星期一'
   when @today=2 then '星期二'
   when @today=3 then '星期三'
   when @today=4 then '星期四'
   when @today=5 then '星期五'
   when @today=6 then '星期六'
   when @today=7 then '星期天'
   else '错误值'
end
   print @week

例子:导入前一天的数据

DECLARE @y varchar(4) 
DECLARE @m varchar(2) 
DECLARE @d varchar(2)

select  @y=DateName(year,GetDate())
select  @d=DateName(day,dateadd(day,-1,GetDate())) 

if (DateName(day,GetDate())='1')/*如果当天是每月1号*/
select  @m=DateName(month,dateadd(MONTH,-1,GetDate()))/*月份-1*/
else
select  @m=DateName(month,GetDate())

EXEC    [dbo].[InsertQYGPSData2]

        @year = @y,

        @month = @m,

        @day = @d

五、游标

1.定位到结果集中的某一行;
2.对当前位置的数据进行读写;
3.可以对结果集中的数据单独操作,而不是整行执行相同操作。
4.是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。

分类:
1.静态游标:不反应结果集中的所有更改
2.动态游标:反应结果集中所有更改
3.只进游标:不支持滚动,只支持从头到尾顺序提取数据
4.键集驱动游标:该游标中的各个成员顺序是固定的的,被标识的列做删改时,用户滚动游标是可见的,未标识则删改不可见。

游标的生命周期:
1.声明游标

declare cursor_name CURSOR [local | global][forward_only | scroll]
[static|keyset|dynamic|fast_forward]
[read_only|scroll_locks|optimistic]
[type_warning]
for select_statement
[for update[of column_name[,...n]]]

注释:

cursor_name:游标名称。
Local:作用域为局部,只在定义它的批处理,存储过程或触发器中有效。
Global:作用域为全局,由连接执行的任何存储过程或批处理中,都可以引用该游标。
[Local | Global]:默认为local。
Forward_Only:指定游标智能从第一行滚到最后一行。Fetch Next是唯一支持的提取选项。如果在指定Forward_Only是不指定Static、KeySet、Dynamic关键字,默认为Dynamic游标。如果Forward_Only和Scroll没有指定,Static、KeySet、Dynamic游标默认为Scroll,Fast_Forward默认为Forward_Only
Static:静态游标
KeySet:键集游标
Dynamic:动态游标,不支持Absolute提取选项
Fast_Forward:指定启用了性能优化的Forward_Only、Read_Only游标。如果指定啦Scroll或For_Update,就不能指定他啦。
Read_Only:不能通过游标对数据进行删改。
Scroll_Locks:将行读入游标是,锁定这些行,确保删除或更新一定会成功。如果指定啦Fast_Forward或Static,就不能指定他啦。
Optimistic:指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。当将行读入游标时,sqlserver不锁定行,它改用timestamp列值的比较结果来确定行读入游标后是否发生了修改,如果表不行timestamp列,它改用校验和值进行确定。如果已修改改行,则尝试进行的定位更新或删除将失败。如果指定啦Fast_Forward,则不能指定他。
Type_Warning:指定将游标从所请求的类型隐式转换为另一种类型时向客户端发送警告信息。
For Update[of column_name ,....] :定义游标中可更新的列。

2.声明一个动态游标:

declare OrderNum_cursor sursor scoll
for select OrderID from bigOrder where OrderNum='xxxx'

3.打开游标

open [Global] cursor_name | cursor_variable_name
              /*游标名 游标变量名*/

4.提取数据

Fetch
[ [Next|prior|Frist|Last|Absoute n|Relative n ]
from ]
[Global] cursor_name
[into @variable_name[,….]]

注释:

Frist:结果集的第一行
Prior:当前位置的上一行
Next:当前位置的下一行
Last:最后一行
Absoute n:从游标的第一行开始数,第n行。
Relative n:从当前位置数,第n行。
Into @variable_name[,...] : 将提取到的数据存放到变量variable_name中。

这里写图片描述
5.利用游标更新删除数据

/*①游标修改当前数据语法*/
Update 基表名 Set 列名=值[,...] Where Current of 游标名 /*②游标删除当前数据语法*/ Delete 基表名 Where Current of 游标名

6.关闭游标

/*关闭游标语法*/
close [ Global ] cursor_name | cursor_variable_name
/*关闭游标*/
close orderNum_03_cursor

7.删除游标

/*释放游标语法*/
deallocate  [ Global ] cursor_name | cursor_variable_name
/*释放游标*/
deallocate orderNum_03_cursor

六、触发器

原理,优点,作用参考:https://www.cnblogs.com/wangprince2017/p/7827091.html

分类:
1.DML:数据操纵语言
insert,delete,update触发器
2.DDl:数据定义语言
create,drop,alter触发器

语法:

CREATE TRIGGER trigger_name ON table_name [WITH ENCRYPTION] FOR | AFTER | INSTEAD OF [DELETE, INSERT, UPDATE] AS T-SQL语句 GO --with encryption 表示加密触发器定义的sql文本 --delete,insert,update指定触发器的类型
/*创建触发器 */
Create trigger User_OnUpdate On ST_User for Update As declare @msg nvarchar(50) /*@msg记录修改情况*/ select @msg = N'姓名从“' + Deleted.Name + N'”修改为“' + Inserted.Name + '”' from Inserted,Deleted /*插入日志表*/ insert into [LOG](MSG)values(@msg) /*删除触发器*/ drop trigger User_OnUpdate

七、自定义函数

1.标量函数:返回的结果是一个标量
例:
这里写图片描述

2.内联表值函数:返回表数据,内联表函数返回的表结构由函数体内的SELECT语句来决定。
例:

create function FUN_Sum1 ( @myid int ) RETURNS table AS RETURN ( select * from St_user where ID<@myid ) GO

3.多语句表值函数:已经定义好要返回的表中的字段

create function FUNC_UserTab_2 ( @myId int ) RETURNS @t table ( [ID] [int] NOT NULL, [Oid] [int] NOT NULL, [Login] [nvarchar](50) NOT NULL, [Rtx] [nvarchar](4) NOT NULL, [Name] [nvarchar](5) NOT NULL, [Password] [nvarchar](max) NULL, [State] [nvarchar](8) NOT NULL ) AS BEGIN insert into @t select * from ST_User where ID<@myId RETURN END GO

4.调用表值函数

select * from dbo.FUNC_UserTab_1(15) 

5.调用标量函数

declare @s int
set @s=dbo.FUNC_Sum1(100,50) 
print @s 

6.删除标量值函数

drop function FUNC_Sum1

尝试写了一个简单的存储过程:

USE [test]
GO
/****** Object: StoredProcedure [dbo].[InsertQYGPSData2] Script Date: 09/05/2018 15:51:27 ******/
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[InsertQYGPSData2] @year varchar(4), @month varchar(2), @day varchar(2) AS BEGIN declare @tablename varchar(20) set @day = right('00'+@day,2) set @tablename='QYGPSData_'+@year+'_'+ @month+'_'+@day IF NOT EXISTS(SELECT NAME FROM sys.objects WHERE NAME=@tablename and TYPE='u') begin exec('create Table ' +@tablename+ ' ( [Create_Date] [datetime] NULL, [CarNum] [varchar](50) NULL, [CarNo] [varchar](50) NULL, [FrontDoorUp] [int] NULL, [FrontDoorDown] [int] NULL, [BackDoorUp] [int] NULL, [BackDoorDown] [int] NULL, [lng] [varchar](50) NULL, [lat] [varchar](50) NULL, [State] [varchar](10) NULL, [CarPassenger] [int] NULL, [Line_Name] [varchar](100) NULL )') end END 

ps:语法:LEFT(ARG,LENGTH)、RIGHT(ARG,LENGTH)

LEFT、RIGHT函数返回ARG最左边、右边的LENGTH个字符串,ARG可以是CHAR或BINARY STRING。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160803.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • [STL] list merge 函数

    [STL] list merge 函数CopyFrom: http://blog.csdn.net/ysuliu/article/details/3497862STLlist容器由于采用了双向迭代器,不支持随机访问,所以标准库的merge(),sort()等功能函数都不适用,list单独实现了merge(),sort()等函数。首先说一下merge()(以voidmerge(list&__x);为例)按照

    2022年5月23日
    38
  • [VB.NET]圖片透明化[通俗易懂]

    [VB.NET]圖片透明化[通俗易懂]原URL:http://www.dotblogs.com.tw/chou/archive/2009/02/12/7120.aspx有沒有辦法做到圖片的透明化,我們可以透過MakeTransparent達成MSDN:Bitmap.MakeTransparent方法:為這個Bitmap將預設的透明色彩變為透明。 而在此程式中,加上了讓使用者點選顏色的功能,並且讓點

    2022年7月21日
    26
  • BetterIntelliJ 激活码_最新在线免费激活2022.02.18

    (BetterIntelliJ 激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年4月1日
    186
  • redis默认端口为什么是6379_redis连接池的作用

    redis默认端口为什么是6379_redis连接池的作用找到redis的安装目录,正常应该都会在/usr/local/下*cd/usr/local/redis-5.0.8*viredis.conf*键入i>>修改默认端口号:6379>>6380,esc>>:wq*redis-server/usr/local/redis-5.0.8/redis.conf

    2022年9月17日
    2
  • Android定时器Timer简单使用「建议收藏」

    Android定时器Timer简单使用「建议收藏」Android定时器Timer简单使用Timer简介Timer使用总结Timer简介Timer(计时器)位于java.util包下,可用于创建定时任务,任务可以安排为一次性执行,也可以定期重复执行。每个计时器对象对应一个后台线程(TimerThread)。简单理解为创建Timer对象,对应TimerThread线程循环开始从TaskQueue队列中执行一个TimerTask任务。Timer使用创建Timer对象vartimer=Timer()添加需要执行的任务//创建计

    2022年7月25日
    11
  • vscode查看源代码_vscode新建python项目

    vscode查看源代码_vscode新建python项目最近从pycharm转到了VScode,但是发现vscode不能跳转到源码,百度之后发现要装一个vscode的python的插件,插件就是「Pylance」。装好这个插件后应该可以使用pycharm一样的快捷方式连接到每个组件的源代码了,具体操作是:1.如果是windows系统,按住Ctrl键+鼠标点击待查看的方法或者类名2.如果是mac系统,按住Command键+…

    2022年8月23日
    27

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号