SQL基本概念

  • T-SQL(Transact Structured Query Language)是标准SQL语言的增强版。标准SQL可以在所有关系型数据库中通用,但T-SQL是SQL server独有的。

  • SQL语句均由一个动词(Verb)开始,描述执行的动作。
    后紧接着一个或多个子句(Clause),子句给出被Verb作用的数据或描述动作的详细信息,每一条子句都由一个关键字开始。

  • 语句分类
    变量说明语句:说明变量的命令;
    数据定义语句:用来建立数据库、数据库对象和定义列,大部分以CREATE开头的命令;
    数据操纵语句:操作数据库中数据,如SELECT、INSERT、UPDATE等;
    数据控制语句:控制数据库组件的存取许可、权限等命令,如GRANT、REVOKE等;
    流程控制语句:设计应用程序流程的语句,如IF、WHILE和CASE等;
    内嵌函数:说明变量的命令。
    其它命令:嵌于命令中使用的标准函数。

常量

*数字常量
整数常量和小数常量直接输入,可加负号,以逗号分隔不同的数字,如12,-100.23
浮点数用符号e指定(类似科学计数),如1.5e3,-34e-8

*字符串常量
单引号标示,可以包含数字、字母、特殊字符、空格、感叹、@、#
可以用两个单引号表示嵌入的单引号。

*日期和时间常量
多种格式,如美国mm/dd/yyyy,欧洲dd.mm.yyyy,中国yyyy-mm-dd等

*符号常量
SQL特有,代表不同的常用数据值。如CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP等。

变量

局部变量

局部变量变量名必须以@开头,符合标识符命名规则

  1. 声明局部变量
DECLARE
{
@varaible_name datatype [, ... n]
}

datatype可以是text, ntext, image类型外的所有数据类型
{}不是必须的

  1. 赋值
    使用SELECT或SET语句
DECLARE @a char(10), @b int
SELECT @a = 'hello world'
SELECT @b = Stu_col FROM table_a WHERE Stu_spe=‘English’
SET @a = 'hi world'
SET @b = 1

注意,DECLARE可以同时声明多个变量,而SET只能为一个变量赋值

全局变量

全局变量以@@开头

常用变量 作用
@@CONNECTIONS 自服务器最近一次启动以来,所有连接数目,包括未成功的尝试
@@CUP_BUSY 自上次启动以来,所有连接以ms为单位的cpu工作时间
@@CURSOR_ROWS 打开游标取出数据行的数目
@@DBTS 返回当前数据库中timestamp数据类型当前值
@@ERROR 返回上一条T-SQL执行的错误代码
@@FETCH_STATUS 返回上一次使用游标FETCH操作返回的状态值,整型,成功0,语句失败-1,被提取的行不存在-2
@@IDENTITY 返回最近一次插入的identity列的数值,numeric值
全局变量2
全局变量3

注释符

-- 单行注释
/* blabla 多行注释 */

运算符Operator

Operator Description
+, -, *, / 加、减、乘、除
% 取余
= Equal
<>、!= Not equal. Note: In some versions of SQL this operator may be written as !=
> Greater than
!> Not greater than
< Less than
!< Not less than
>= Greater than or equal
<= Less than or equal
& 按位与(整型或二进制数据类型)
| 按位或(整型或二进制数据类型)
~ 按位非(整型或二进制数据类型)
^ 按位异或(整型或二进制数据类型)
AND, OR, NOT 逻辑与、或、非
+ 链接字符串
以下逻辑运算符 通常与比较运算符连用
ANY 任意一个true,结果为true
ALL 全部为true,结果为true
BETWEEN ... AND Between an inclusive range
EXISTS 存在则为true
LIKE Search for a pattern,模式匹配则为true
IN '=ANY', To specify multiple possible values for a column

操作符

  • AND操作符
    要通过不止一个列进行果过滤,可以使用AND操作符对WHERE子句附加条件,用在WHERE子句中的关键字
  • OR 操作符
    OR操作符与AND操作符正好相反,它告诉DBMS检索匹配任一条件的行,事实上,许多DBMS在OR WHERE 子句的第一个条件得到满足的情况下就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来。
  • IN 操作符
    In操作符用来指定条件范围,范围中的每个条件都可以进行匹配,in取一组逗号分隔,括在圆括号中的合法值IN 操作符允许我们在 WHERE 子句中规定多个值
SELECT column_name(s) FROM table_name
WHERE column_name IN (value1,value2,...) 
  • NOT操作符
    WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件,因为NOT从不单独使用,(他总是与其他操作符一起使用),所以了他的语法与其他操作符有所不同,NOT关键字可以用在要过滤的列前,而不仅是在其后.

  • AS
    Alias 语法
    表的SQL Alias语法

SELECT column_name(s)
FROM table_name
AS alias_name

列的SQL Alias语法

SELECT column_name AS alias_name
FROM table_name

通配符

Operator Description
% 匹配0到多个字符的字符串
_ 匹配单个字符
[] 如[a-z],匹配指定范围或集合内的单个字符
[^] [^a-c], 匹配不在指定范围或集合内的单个字符

流程控制

BEGIN…END

流程控制语句必须执行一个包含两条或两条以上的SQL语句块时使用

BEGIN
    sql_statements...
END

在BEGIN...END中可以嵌套另外的BEGIN...END来定义另一程序块。

IF... ELSE

选择判断结构,可以单独IF使用,可以结合ELSE使用

IF<条件表达式>
      命令行1 | 程序块1
ELSE
      命令行2 | 程序块2

由于IF没有END结构,所以命令行只能一行,否则使用BEGIN...END程序块。IF判断为真执行IF后命令,为假则执行再下一条语句。

CASE

多重选择语句
用于计算条件列表的表达式,并返回可能的结果之一。
sql 的case 类型于编程语言里的 if-esle if-else 或者 switch,但它不用于控制sql程序的执行流程,而是作为列的逻辑使用。

case [input_expression]
when when_expression then result_expression
[...n]
[else else_result_expression]
end
注:其中[]内都是可选的。

简单case函数(case后加表达式,则根据表达式结果返回。)

--简单case函数
select *,
    case sex
    when '1' then '男'
    when '2' then '女’
    else '其他' end groupname
from @table

case搜索函数。(case 后不加表达式,则根据when的条件返回)

--case搜索函数
select *,
    case 
    when sex = '1' then '男'
    when sex = '2' then '女'
    else '其他' end comment
from @table 

这两种方式,可以实现相同的功能。简单case函数的写法相对比较简洁,但是和case搜索函数相比,功能方面会有些限制,比如写判定式。
还有一个需要注重的问题,case函数只返回第一个符合条件的值,剩下的case部分将会被自动忽略。

--比如说,下面这段sql,你永远无法得到“第二类”这个结果
case when col_1 in ('a','b') then '第一类'
     when col_1 in ('a') then '第二类'
     else '其他' end  

将sum与case结合使用,可以实现分段统计。
如果现在希望将上表中各种性别的人数进行统计,sql语句如下:

SQL> select
  2    sum(case u.sex when 1 then 1 else 0 end)男性,
  3    sum(case u.sex when 2 then 1 else 0 end)女性,
  4    sum(case when u.sex <>1 and u.sex<>2 then 1 else 0 end)性别为空
  5  from users u;
 
        男性         女性       性别为空
---------- ---------- ----------
         3          2          0

--------------------------------------------------------------------------------
SQL> select
  2    count(case when u.sex=1 then 1 end)男性,
  3    count(case when u.sex=2 then 1 end)女,
  4    count(case when u.sex <>1 and u.sex<>2 then 1 end)性别为空
  5  from users u;
 
        男性          女       性别为空
---------- ---------- ----------
         3          2          0

将case与order by一起使用,可实现复杂排序
如下,存储过程需要支持多种排序,可以传递一个参数变量,然后根据该变量判断操作。

declare @orderby int
set @orderby = 1
 
select * from @stuinfo
order by
    case when @orderby = 1 then id end desc,
    case when @orderby = 2 then id end

注意:这里要用多个case,因为desc需要放在end 后面,否则会有语法错误。

WHILE

设置重复执行 SQL 语句或语句块的条件。只要指定的条件为真,就重复执行语句。可以使用 BREAK 和 CONTINUE 关键字在循环内部控制 WHILE 循环中语句的执行。
循环结构,执行其后一条命令,或配合BEGIN...END子句执行该程序块
语法

WHILE Boolean_expression
{ sql_statement | statement_block }
[ BREAK ]
{ sql_statement | statement_block }
[ CONTINUE ]

参数

  • Boolean_expression
    返回 TRUE 或 FALSE 的表达式。如果布尔表达式中含有 SELECT 语句,必须用圆括号将 SELECT 语句括起来。

  • {sql_statement | statement_block}
    Transact-SQL 语句或用语句块定义的语句分组。若要定义语句块,请使用控制流关键字 BEGIN 和 END。

WHILE<条件表达式>
BEGIN
      <命令行 | 程序块>
END

还可以使用CONTINUE和BREAK命令,控制循环执行

WHILE<条件表达式>
BEGIN
      <命令行 | 程序块>
      [BREAK]
      [CONTINUE]
      [命令行 | 程序块]
END

CONTINUE可以放在IF里,满足一定条件则路过后续,继续执行新一个loop
BREAK也可以放在IF语句里,满足条件后直接中断结束WHILE,执行后续语句

  • BREAK
    导致从最内层的 WHILE 循环中退出。将执行出现在 END 关键字后面的任何语句,END 关键字为循环结束标记。

  • CONTINUE
    使 WHILE 循环重新开始执行,忽略 CONTINUE 关键字后的任何语句。

注释
如果嵌套了两个或多个 WHILE 循环,内层的 BREAK 将导致退出到下一个外层循环。首先运行内层循环结束之后的所有语句,然后下一个外层循环重新开始执行。

RETURN

从查询或过程中无条件退出。RETURN后语句不会被执行。
RETURN [返回值]

返回值

GOTO

程序跳到标识符指定的程序行继续执行。
GOTO 标识符
此处标识符要在名称后加冒号‘:’,如“here:”
与while 语句结合可以实现WHILE...END的功能

DECLARE @X INT
SELECT @X = 1
here:
    PRINT @X
    SELECT @X = @X+1
WHILE @X<=3 GOTO here

WAITFOR

指定触发器、存储过程或事务执行时间,也可以用来暂停程序执行
WAITFOR DELAY<'时间'> | TIME<‘时间’>
其中时间必须为DATETIME类型,不能包括日期。
DELAY用来设定等待时间,最长24小时
TIME用来设定等待结束的时间点。

常用命令

  • DECLARE
  • PRINT
    向客户端显示一个字符串(最长255字符)、局部变量或全局变量的内容
    PRINT msg_str | @local_variable | string_expr
  • READTEXT
    读取text、ntext或image列中的值,从指定位置开始读取指定字符数
    READTEXT table.column text_ptr offset size [HOLDLOCK]
READTEXT命令参数说明
  • SELECT
    查询,赋值均可实现

  • SET
    赋值,功能更强更严密,推荐使用

  • USE
    在当前工作区打开数据库

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容