目录
在SQLserver的应用操作中,存储过程和触发器扮演着相当重要的角色,其基于预编译并存储在SQLserver数据中的特性,不仅能提高应用效率,确保一致性,完成业务规则,更能提高系统运行的速度。这章内容我主要学习数据库编程,学习存储过程,触发器等数据库高级对象的创建。
一,了解T-SQL语言
SQL是关系数据库的标准语言,可以在所有关系数据库上使用,T-SQL(Transaction Structured Query Language)是标准SQL的一种扩展,我们不仅可以利用T-SQL编写的数据库程序完成数据库的各种操作,还可以将其嵌入其他语言,用来让程序与SQLserver沟通。
T-SQL是SQLserver系列产品独有的。
1,常量(标量值)
表示一个特定数据值的符号。常量的格式取决于它所表示的数据类型:
-
数字常量。
包括整数常量,小数常量和浮点数常量。
整数常量和小数常量被写成普通的数字形式,由符号(-),数字和小数点构成。
浮点数常量使用e来指定,常用来表示特别大或者特别小的数据,例如
可以看到,与其他编程语言不同,T-SQL对于小数的分类有两种:小数和浮点数。
如果是其他编程语言,对于小数,都统称为浮点数类型。使用float或double定义。
-
字符串变量。
内容包含在单引号内,如果字符串本身包含单引号,则使用两个单引号表示。
例如,字符串 I'am a Chinese,表示为 'I'' am a Chinese'。 -
日期和时间常量是放在单引号中,由日期,时间以及间隔符构成,例如'1984-03-10'或'03/31/2021'。
2,变量
T-SQL中有两类变量:全局变量和局部变量。
局部变量名必须以一个@开头,全局变量名以两个@开头。
1)局部变量
局部变量是用户可定义的变量,只具有局部作用范围(在定义它的语句,批处理或中中使用)。
局部变量用DECLARE命令声明,语法格式如下:
sql
DECLARE @局部变量名 数据类型[,...n]
用SELECT 或SEL给局部变量赋值,语法如下:
sql
SET @局部变量名=具体值 --只给一个局部变量赋值
--或
SELECT @局部变量名=表达式[,...] --可以同时给多个局部变量赋值
任务1,声明一个可以存储10个字符的局部变量@id,并给它赋值"1000010000"。
编写语句如下:
sql
DECLARE @id char(10)
SET @id='1000010000'
任务2,查询"SQLserver DataBase Application principle"课程的学分和学时,保存在变量中。
编写语句如下:
sql
DECLARE @cct int, @cpd int
SELECT @cct=cct,@cpd=cpd
FROM courses
WHERE cne='SQLserver DataBase Application principle'
如果想要显示变量的值,可以使用以下两个语法。
可以直接用SELECT显示变量,语法格式如下:
sql
SELECT 变量名[,...n]
还可以使用PRINT语句,语法如下:
sql
PRINT ''+STR(@局部变量名,length) --STR函数用于将数值转换为字符串,length表示浮点数转换时的最大长度
sql
PRINT 'courses credit (cct)='+STR(@cct,2)+CHAR(10)+
'courses period(cpd)='+STR(@cpd,2)
--CHAR(9):制表符
--CHAR(10):换行符
--CHAR(13):回车
2)全局变量
全局变量是SQL server系统定义并赋值的变量,用来记录SQL server的配置设定值和效能统计等数据。用户不能定义全局变量,也不能给全局变量赋值,只能读取。
常用的全局变量如下表所示👇
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 全局变量名称 | 含义 |
| @@version | 当前的SQL server安装的版本,处理器体系结构,生成日期和操作系统 sql PRINT 'Current version of the SQL server installation='+@@version
|
| @@rowcount | 上一条T-SQL语句影响到的数据行数,如下: sql PRINT 'The number of rows of data affected by the previous T-SQL statement='+STR(@@rowcount,2)
|
| @@error | 执行的上一条T-SQL语句错误号。 |
| @@connections | 自SQL server最后一次启动以来,连接或试图连接到SQL server的连接数目 sql PRINT 'Number of SQL server connections='+STR(@@connections)
|
[常用的全局变量]
二,内置函数
SQL server提供了很多内置函数,通过与查询,添加,更新和删除等操作的配合使用,可实现更复杂的功能。T-SQL的常用内置函数有字符串函数,数学函数,日期时间函数和转换函数。
1,字符串函数
|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 函数 | 功能描述 |
| ASCII(character) | 返回character的ASCII整数值。参数为字符串时,只取第一个字符。 sql PRINT 'ASCII(''ABC'')='+STR(ASCII('ABC'))
可以看到,字符'A'的ASCII码值为65。 |
| CHAR(integer) | 返回给定ASCII整数值对应的字符。参数integer为0~255之间的整数。 例如,之前学习的返回一个换行符:CHAR(10) sql PRINT 'A'+CHAR(10)+'B'
|
| SPACE(integer) | 返回指定个数的空格。 sql PRINT 'A'+SPACE(10)+'B'
|
| STR(float,length,decimal) | 将给定的浮点数float转换成字符串。 length:浮点数转换时的最大长度。 decimal:浮点数转换时保留的小数个数。 例如输出:今年是2024年。 sql PRINT 'This year is'+SPACE(1)+STR(2024,4)+SPACE(1)+'year'
|
| LEN(string) | 返回字符串中的字符个数。 |
| |
| LOWER(string) | 将字符串中的字符全部转换为小写。 sql DECLARE @s VARCHAR(100) SET @s=LOWER('HELLO WORLD') PRINT @s
|
| UPPER(string) | 和LOWER函数相反,UPPER函数将字符串中的字符全部转换为大写,如下: sql DECLARE @s VARCHAR(100) SET @s=LOWER('HELLO WORLD') PRINT UPPER(@s)
|
| LTRIM(string) | 删除字符串前面(即左边left)的所有空格。 未删除左边空格: 删除左边空格: |
| RTRIM(string) | 删除字符串后面(即右边right)的所有空格。 我发现,如果一个字符串的末尾是空格,在统计字符长度时,并不会加上空格的长度: 因此,我感觉这个函数会用得比较少(毕竟不用也没啥影响)。 |
| LEFT(string,integer) | 返回字符串从左边开始的指定个数的字符。 |
| RIGHT(string,integer) | 返回字符串从右变开始的指定个数的字符。 删除字符右边的空格,之后再输出结果: |
| SUBSTRING(string1,start,length) | 从字符串的指定位置开始,返回指定个数的字符。例如返回字符串s的全部内容: |
| REPLACE(string1,string2,string3) | 从字符串中的指定内容进行替换。 原始字符串string1 使用新的字符串string3,替换原始字符串string1中的字符串string2 |
| STUFF(string1,start,length,string2) | 将字符串插入另一个字符串。 首先删除字符串string1从sart开始共length个字符 之后在字符串string1的开始位置插入字符串string3 sql DECLARE @s VARCHAR(100) SET @s='HELLO WORLD ' PRINT STUFF(@s,1,LEN(@s),'do better every day')
|
| CHARINDEX(string1,string2,start) | 在字符串string2中从start指定的字符开始搜索字符串string1,并返回其起始位置,如果没有找到则返回0。 |
| PATINDEX('%pattern%',string) | 按照指定模式在字符串string中查找,返回匹配内容第一次出现的起始位置,如果没有找到则返回0。 |
[字符串函数]
2,数学函数
SQL server的数学函数可以实现各种数学运算,常用的数学函数如下表所示:
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 函数 | 功能描述 |
| ABS(number) | 返回给定数字的绝对值。 |
| EXP(number) | 返回给定数字的指数值。即 |
| SQRT(number) | 返回给定数字的平方根。 |
| CEILING(number) 天花板 | (向上取整)。返回大于或等于给定数字的最小整数。 |
| FLOOR(number) 地面 | (向上取整)。返回小于或等于给定数字的最大整数。 |
| RAND() RAND(number) | 返回一个0到1之间的随机小数。 函数为空的参数时,随机数会随着运行而改变👇 第一次运行: 第二次运行: 第三次运行: 当我向函数中传入一个数字,随机数就不会随着程序的运行而改变👇 |
| SIGN(number) | 返回number的正负号。number为正时返回1,为0时返回0,为负数时返回-1。 |
| POWER(n,a) | 返回给定数字的乘幂。即 |
| LOG(number) | 返回给定数字的自然对数,即以e为底数的对数值 计算对数的结果可以使用泰勒级数展开或者是数值积分及查表。也可以直接使用LOG函数得到。 |
| LOG10(number) | 返回给定数字的以10为底数的对数值。 |
| PI() | 返回Π的常量值3.14159265358979,精确到小数点后14位?但我在使用的时候发现只能精确到小数点后5位👇 |
[数学函数]
3,日期时间函数
|--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 函数 | 功能 |
| GetDate() | 获取当前系统日期和时间。 sql DECLARE @d datetime SET @d=GETDATE() PRINT @d
|
| YEAR(date) | 返回日期date中的"年份"。 |
| MONTH(date) | 返回日期date中的"月份"。 |
| DAY(date) | 返回日期date中的"日"。 |
| DATEPART(datepart,date) | 返回日期date中指定datepart的整数。 例如,返回日期@d中的年份👇 |
| DATENAME(datepart,date) | 返回date中指定detepart的字符串。 |
| DATEADD(datepart,number,date) | 将指定number时间间隔(有符号整数)与指定日期date(@d)的指定datepart相加后,返回该date。. 例如,在日期@d的年份基础上加上1。 |
| DATEDIFF(datepart,startdate,enddate) | 返回指定的startdate和enddate之间所跨的指定datepart边界的计数。 sql DECLARE @d1 datetime='2003/12/02' DECLARE @d2 datetime =GETDATE(); PRINT DATEDIFF(year,@d1,@d2)
|
[日期时间函数]
其中,参数detepart的取值如下表所示。
|-------------|---------|------------------------------------------------------------------|
| 日期部分 | 缩写 | 含义 |
| year | yy,yyyy | 年 |
| quarter | qq,q | 季度,1~4 |
| month | mm,m | 月,1~12 |
| dayofyear | dy,y | 一年中的第几日,1~366 |
| day | dd,d | 一月中的第几日,1~31 |
| week | wk,ww | 一年中的第几周,1~52 |
| weekday | Dw | 星期几,一个星期从星期日开始, DATENAME函数返回星期日到星期六; DATEPART返回1~7(1:星期日,2:星期一) |
| hour | Hh | 小时 |
| minute | min | 分钟 |
| second | ss,s | 秒 |
| millisecond | ms | 毫秒 |
[datepart]
小任务:查询所有学生的学号,姓名和年龄。
编写语句如下:
sql
USE StuScore
UPDATE students SET sbd='2003-12-2' WHERE sno=2
-- 根据查询记录创建新的表
DROP TABLE S1
SELECT sno AS 学号,sne AS 姓名,YEAR(GETDATE())-YEAR(sbd) AS 年龄 --DATEDIFF(year,sbd,GETDATE()) AS 年龄
INTO S1
FROM students
SELECT sne,sbd FROM students
SELECT * FROM S1
4,转换函数
转换函数可以进行数据类型转换。
在一般情况下,SQLserver会自动完成数据类型的转换,但当数据类型无法自动转换时,需要用户通过数据库提供的函数来转换。有以下两个转换函数。
-
CAST(expression as data_type [(length)])
将表达式expression表示的值转换为参数data_type指定的目标数据类型;
参数length 指定目标数据类型长度,是可选参数,默认值为30。
如下,将字符串类型转换成日期类型。
-
CONVERT(date_type[(length)],expression[,style])
与CAST函数的功能类似,参数style规定日期/时间的输出方式。
如下,以不同格式输出系统当前时间。
sqlPRINT CONVERT(VARCHAR(20),GETDATE()) --字符串形式输出日期 +CHAR(10) +CONVERT(VARCHAR(20),GETDATE(),110) +CHAR(10) +CONVERT(VARCHAR(20),GETDATE(),120)
三,批处理
批处理是包含一个或多个T-SQL语句的组,从客户端一次性地发送到服务器端。
SQLserver服务器将批处理语句编译成一个执行单元。
批处理能够有效地减少客户端到服务器的网络往返次数。
GO:
- GO是批处理的结束符。
- 当遇到GO关键字时,GO之前的语句会作为一个批处理直接传到SQLserver实例执行。
- GO关键字本身并不是一个T-SQL语句。
一般一个批处理中可以包含多条T-SQL语句,但是有一些特殊的地方:
以CREATE关键字开头的语句必须是批处理中唯一的语句:
- CREATE RULE
- CREATE DEFAULT
- CREATE PROCEDURE
- CREATE TRIGGER
- CREATE VIEW
小任务:使用学生成绩管理数据创建表table1,视图view1。
如果不在创建视图的语句前面加上GO关键字,就会报错。
有问题请在评论区留言或者是私信我,回复时间不超过一天。