--select left(字段,charindex('-',字段)-1) from 表名left(className,charindex('1',className)-1) from class
《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的
内容
,以及SQL Server 2008新增加的一些特性。主要
内容
包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决方案。
作为一本讲述T-SQL高级查询的专业图书,《Microsoft SQL Server 2008技术内幕:T-SQL查询》旨在结合实践中的各种常见问题,教读者如何用SQL作为语言工具来思考问题,揭示基于集合查询的强大威力。《Microsoft SQL Server 2008技术内幕:T-SQL查询》
内容
丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询》,可以充分地理解T-SQL语言和良好的编程实践,学会如何编写更加有效而强大的查询语句。
致谢III
前
言 V
第1章 逻辑查询处理1
1.1 逻辑查询处理的各个阶段2
1.1.1 逻辑查询处理阶段简介2
1.2 客户/订单场景下的查询示例4
1.3 逻辑查询处理阶段详解5
1.3.1 步骤1:FROM阶段5
1.3.2 步骤2:WHERE阶段9
1.3.3 步骤3:GROUP BY阶段10
1.3.4 步骤4:HAVING阶段11
1.3.5 步骤5:SELECT阶段12
1.3.6 步骤6:排序用的ORDER BY阶段13
1.4 逻辑查询处理的深入
内容
16
1.4.1 表运算符16
1.4.2 OVER子句23
1.4.3 集合运算符25
1.5 总结26
第2章 集合论和谓词逻辑27
2.1 自然语言表述到数学表示的转换27
2.1.1 严格定义(well-Definedness)28
2.1.2 相等、恒等和同一性30
2.1.3 数学命名约定30
2.1.4 数字31
2.1.5 上下文32
2.1.6 函数、参数和变量33
2.1.7 指令和算法34
2.2 集合论34
2.2.1 集合的标记方法35
2.2.2 集合的严格定义36
2.2.3 论域36
2.2.4 真实性38
2.2.5 罗素悖论(Russell s Paradox)40
2.2.6 有序对、元组和笛卡尔积41
2.2.7 空集42
2.2.8 集合的特征函数43
2.2.9 集合的基数(Cardinality)43
2.2.10 顺序44
2.2.11 集合运算符47
2.2.12 集合论的推广50
2.3 谓词逻辑50
2.3.1 编程语言中的逻辑功能50
2.3.2 命题和谓词51
2.3.3 排中律53
2.3.4 与、或、非运算53
2.3.5 逻辑等价55
2.3.6 逻辑蕴含55
2.3.7 量化(Quantification)56
2.3.8 替代和推广58
2.4 关系59
2.4.1 自反性、对称性和传递性59
2.5
一个
实际的应用60
2.6 总结63
第3章 关系模型65
3.1 关系模型简介65
3.1.1 关系、元组和类型65
3.1.2 关系模型:快速摘要70
3.2 关系代数和关系计算70
3.2.1 基本运算符71
3.2.2 关系代数71
3.2.3 Codd提出的8个原始关系运算符72
3.2.4 关系演算79
T-SQL支持80
3.3 数据完整性81
3.3.1 声明式约束82
3.3.2 实施完整性的其他方法84
3.4
数据库
正规化和其他设计主题86
3.4.1 解决函数依赖的范式87
3.4.2 更高级的范式92
3.4.3 反规范化(Denormalization)95
3.4.4 一般化和特殊化96
3.5 总结98
第4章 查询优化99
4.1 本章用到的样本数据99
4.2 优化方法论102
4.2.1 分析实例级别的等待104
4.2.2 关联等待和队列111
4.2.3 确定行动方案112
4.2.4 细化到
数据库
/文件级别113
4.2.5 细化到进程级别115
4.2.6 优化索引和查询132
4.3 查询优化的工具133
4.3.1 查询执行计划的缓存133
4.3.2 清空缓存134
4.3.3 动态管理对象134
4.3.4 STATISTICS IO135
4.3.5 测量查询的运行时间135
4.3.6 分析执行计划136
4.3.7 图形化的执行计划136
4.3.8 提示(Hint)144
4.3.9 跟踪/Profiler145
4.3.10
数据库
引擎优化顾问145
4.3.11 数据收集和管理数据仓库146
4.3.12 使用SMO来复制统计信息146
4.4 索引优化146
4.4.1 表和索引的结构146
4.4.2 索引访问方法153
4.4.3 索引策略的分析191
4.4.4 碎片200
4.4.5 分区201
4.5 准备样本数据202
4.5.1 数据准备202
4.5.2 TABLESAMPLE206
4.6 基于集合的方法和迭代/过程方法的比较,以及
一个
优化练习208
4.7 总结214
第5章 算法和复杂性215
5.1 你有
一个
1夸特的硬币吗?215
5.1.1 如何从零钱罐中
取
回1夸特钱216
5.1.2 有时零钱罐中没有1夸特的硬币216
5.2 如何度量算法(How Algorithms Scale)217
5.2.1 二次缩放(Quadratic Scaling)的
一个
例子217
5.2.2 具有线性复杂度的算法218
5.2.3 指数和超指数复杂度218
5.2.4 次线性(sublinear)复杂度219
5.2.5 常量复杂度219
5.2.6 复杂度的技术定义220
5.2.7 复杂度的比较221
5.3 经典算法和算法策略222
5.3.1 排序算法223
5.3.2
字符串
查找225
5.4
一个
实际的应用程序226
5.4.1 识别测量数据的趋势226
5.4.2 LISLP算法的复杂度226
5.4.3 用T-SQL解决最长上升子序列的长度问题227
5.5 总结229
第6章 子查询、表表达式和排名函数231
6.1 子查询232
6.1.1 独立子查询232
6.1.2 相关子查询235
6.1.3 行为不当的子查询244
6.1.4 不常用的谓词245
6.2 表表达式(Table Expressions)246
6.2.1 派生表247
6.2.2 公用表表达式249
6.3 分析排名函数255
6.3.1 行号257
6.3.2 排名和密集排名(Dense Rank)271
6.3.3 组号(Tile Number)272
6.4 数字辅助表276
6.5 缺失范围和现有范围(也称为间断和孤岛)279
6.5.1 缺失范围(间断)281
6.5.2 现有范围(孤岛)288
6.6 总结296
第7章 联接和集合运算297
7.1 联接297
7.1.1 旧语法和新语法297
7.1.2 基本联接类型298
7.1.3 其他的联接分类306
7.1.4 上一年度的滑动合计317
7.1.5 联接算法320
7.1.6 拆分元素326
7.2 集合运算332
7.2.1 UNION332
7.2.2 EXCEPT333
7.2.3 INTERSECT334
7.2.4 集合运算的优先级335
7.2.5 在集合运算中使用INTO336
7.2.6 避开不支持的逻辑阶段336
7.3 总结338
第8章 数据聚合和透视339
8.1 OVER 子句339
8.2 决胜属性(Tiebreaker)341
8.3 连续聚合343
8.3.1 累积聚合(Cumulative Aggregation)344
8.3.2 滑动聚合(Sliding Aggregation)348
8.3.3 年初至今(YTD)349
8.4 透视转换(Pivoting)350
8.4.1 透视转换属性350
8.4.2 关系除法353
8.4.3 聚合数据355
8.5 逆透视转换357
8.6 自定义聚合360
8.6.1 使用透视转换的自定义聚合361
8.6.2 用户定义聚合函数(UDA,User Defined Aggregate)362
8.6.3 专用解决方案370
8.7 直方图(Histogram)380
8.8 分组因子383
8.9 分组集385
8.9.1 样例数据386
8.9.2 GROUPING SETS从属子句387
8.9.3 CUBE从属子句389
8.9.4 ROLLUP从属子句390
8.9.5 分组集代数392
8.9.6 GROUPING_ID函数395
8.9.7 保存分组集397
8.9.8 排序399
8.10 总结400
第9章 TOP和APPLY401
9.1 SELECT TOP401
9.1.1 TOP和确定性402
9.1.2 TOP和输入表达式403
9.1.3 TOP和修改404
9.1.4 增强的TOP406
9.2 APPLY407
9.3 使用TOP和APPLY解决常见问题408
9.3.1 每组中的TOP n408
9.3.2 匹配当
前
值和
前
一个
值413
9.3.3 分页416
9.4 逻辑转换422
9.5 总结424
第10章 数据修改425
10.1 插入数据425
10.1.1 增强的VALUES子句425
10.1.2 SELECT INTO426
10.1.3 BULK行集提供程序428
10.1.4 按最小方式记录日志的操作430
10.1.5 INSERT EXEC447
10.1.6 序列机制450
10.2 删除数据454
10.2.1 TRUNCATE与DELETE454
10.2.2 删除包含重复数据的行455
10.2.3 基于联结的DELETE456
10.3 更新数据458
10.3.1 基于联结的UPDATE458
10.3.3 更新大值数据类型461
10.3.3 用SELECT和UPDATE语句进行赋值462
10.4 合并数据465
10.4.1 MERGE语句基础467
10.4.2 额外增加
一个
谓词470
10.4.3 多个WHEN子句471
10.4.4 WHEN NOT MATCHED BY SOURCE子句472
10.4.5 MERGE Values473
10.4.6 MERGE与触发器474
10.5 OUTPUT子句475
10.6 总结482
第11章 查询分区表483
11.1 在SQL Server中进行分区483
11.1.1 分区视图483
11.1.2 分区表484
11.2 总结496
第12章 图、树、层次结构和递归查询497
12.1 术语497
12.1.1 图497
12.1.2 树498
12.1.3 层次结构498
12.2 应用场景498
12.2.1 员工组织图499
12.2.2 材料清单(BOM)500
12.2.3 道路系统503
12.3 迭代/递归506
12.3.1 下属506
12.3.2 祖先514
12.3.3 带有路径枚举的子图/子树517
12.3.4 排序519
12.3.5 环521
12.4 具体化路径524
12.4.1 维护数据524
12.4.2 查询529
12.5 使用HIERARCHYID数据类型的具体化路径533
12.5.1 维护数据534
12.5.2 查询539
12.5.3 使用HIERARCHYID的其他方面542
12.6 嵌套集合550
12.6.1 分配左值和右值551
12.6.2 查询555
12.7 传递闭包(Transitive Closure)557
12.7.1 有向无环图557
12.7.2 无向有环图561
12.8 总结568
自己写的
数据库
装载工具,平时工作中用于装载大文本文件到
数据库
表,也能直接装载excel,不过excel只能使用
第一个
sheet,且不支持合并的单元格。
jdk要求版本1.6及以上。
使用方法: java -jar lynload.jar,即可看到中文命令行参数(unix下需设置gbk
字符
集环境才能看中文,没gbk环境不能看中文,但不影响导入数据)。
1.同时支持多个
数据库
.
2.支持任意
字符串
作为列分隔符,什么竖线逗号或者十六进制
字符
及任意组合
字符串
都行
3.支持任意
字符串
作为每行分隔符,例如\r,\r\n,或者十六进制
字符
或任意指定的
字符串
(例如可实现把整个日志文件装入
数据库
的单个clob
字段
).
4.支持任意大小的文本,装入几十GB都试过没问题。
5.明确到每一行的错误信息.(装载时会生成
一个
.err文件,里面有装载出错的每一行错误原因(少
字段
还是格式不符合要求等等)。
6.可以作为库使用在jsp等后台直接调用,将整个jar作为库,使用
OraLoad类的int ProcLoad(Connection in_conn, String args[])函数就可以实现类似功能了。例如 new OraLoad.ProcLoad( null, "-u test -p testpwd -i 127.0.0.1 -s ora10 -f test.txt -t tmp_test -c , -e gbk");
具体参数如下:
Usage:
-db database type
1或者oracle, oracle
数据库
,不区分大小写,默认1,需java1.5及以上版本
2或者
sqlserver
, ms
sqlserver
数据库
,不区分大小写,需java1.6及以上版本
3或者mysql, mysql
数据库
,不区分大小写,需java1.5及以上版本
4或者sybase, sybase
数据库
,不区分大小写(暂未测试)
数据库
连接的url.默认空
字符串
如果有url参数,则-i-p-s-dn参数全无效。
如果没有url参数,则必须提供-i-p-s参数,程序里面好拼凑url
例如: jdbc:
sqlserver
://localhost:1433; DatabaseName=sample
-i ip address:port
ip地址和端口,中间用冒号隔开
url不为空则此参数无效
如果不带端口,系统根据
数据库
类型采用默认端口
oracle
数据库
: 默认为1521端口
sqlserver
数据库
: 默认为1433端口
mysql
数据库
: 默认为3306端口
sybase
数据库
: 默认为5000端口
例如: 127.0.0.1:1521
例如: 192.168.0.1
-s serviceid or database name
oracle服务名或者其他
数据库
的
数据库
名
url不为空则此参数无效
-u username
用户名,必输
-p Password
登录密码,必输
-t TableName
要插入的表名,可以带用户,必输
例如: scott.emp 或者 emp都行
-f FileName
来源的文件名,必输
-ff FileName format
来源的文件名类型:txt,文本文件;xls:Excel2003或2007文件),默认是txt
对于Excel文件的导入,仅导入
第一个
sheet的
内容
,其他sheet的
内容
忽略
-e Encoding
文件的编码,默认gbk
-c Cut split string
分隔
字符串
,可以是多个
字符
组合,默认竖线
-r commit rows
每插入多少行提交一次,-1表示不提交,默认-1,如果设置了ac参数为1,则此参数无效。
注意:如果设置了此参数,每到此行数会执行一次commit,如果是外部调用此过程要注意所有数据会被提交
-ac all commit
0.插入成功的都提交,失败的登记文本,默认0; 1.全部插入成功后才提交(有失败则回滚并结束)
-a column flag
第一行的类型
0.没有列名行,默认0。此值为0则it参数不生效。
1.第一行是逗号分隔的包括列类型的列信息,例如NAME VARCHAR2(30),注意,区分大小写
2.第一行是列分隔符分隔的列名(不包括列
字段
信息),注意,列名区分大小写
-it insert type
1.导入的列需要跟
数据库
列名个数及名称完全相同,顺序无所谓,默认1
2.仅导入文件
字段
名与
数据库
字段
名完全相同的数据,顺序无所谓
3.第一行是列信息,按此列信息创建新表导入数据(暂不用)
4.忽略第一行,无论第一行是什么数据全部忽略,从第二行按列
字段
顺序匹配装载
必须在-a 参数 > 0时才生效,否则无意义
-d date formate
日期格式,参考java的SimpleDateFormate类参数,默认自动识别
可识别格式:yyyyMMdd, yyyy-MM-dd, yyyy/MM/dd, yyyyMMdd:HHmmss(等于oracle的yyyymmdd:hh24miss)
yyyy年,MM月,dd日,HH 24小时制时,hh 12小时制时,mm 分, ss秒
-l line end string
每条记录结尾的分隔符,默认是 \r\n回车换行符,支持
前面
-c参数说的转义符
oracle例子: 登陆scott用户,裝载a.txt的逗号分隔的gbk编码文本
内容
到scott.emp
java -jar xxx.jar -i 127.0.0.1 -p 1521 -s ora10 -u system -p manager -t scott.emp -f a.txt -c ,
sqlserver
例子: 登陆11.8.126.181
数据库
的test用户,裝载f: est.xlsx的excel数据到tmp_i表
java -jar -db
sqlserver
-i 11.8.126.181 -s abcd -u test -w test -f f: est.xlsx -t tmp_i -ff xls
mysql例子: 登陆本机
数据库
的root用户,裝载a.txt的文本数据到tmp_i表,不提交
java -jar xxx.jar -db mysql -i 127.0.0.1 -s gjjgj -u root -w root -f a.txt -t tmp_i
《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的
内容
,以及SQL Server 2008新增加的一些特性。主要
内容
包括SQL的基础理论、查询优化、查询算法及复杂度,以及在使用子查询、表表达式、排名函数、数据聚合和透视转换、TOP和APPLY、数据修改、分区表、特殊数据结构等实际应用时会遇到的各种高级查询问题和解决方案。
作为一本讲述T-SQL高级查询的专业图书,《Microsoft SQL Server 2008技术内幕:T-SQL查询》旨在结合实践中的各种常见问题,教读者如何用SQL作为语言工具来思考问题,揭示基于集合查询的强大威力。《Microsoft SQL Server 2008技术内幕:T-SQL查询》
内容
丰富、文字简洁明快,列举的实例具有一定的难度,而且实用性很强,可以把它们作为解决实际问题的标准模式。阅读《Microsoft SQL Server 2008技术内幕:T-SQL查询》,可以充分地理解T-SQL语言和良好的编程实践,学会如何编写更加有效而强大的查询语句。
致谢III
前
言 V
第1章 逻辑查询处理
1.1 逻辑查询处理的各个阶段
1.1.1 逻辑查询处理阶段简介
1.2 客户/订单场景下的查询示例
1.3 逻辑查询处理阶段详解
1.3.1 步骤1:FROM阶段
1.3.2 步骤2:WHERE阶段
1.3.3 步骤3:GROUP BY阶段
1.3.4 步骤4:HAVING阶段
1.3.5 步骤5:SELECT阶段
1.3.6 步骤6:排序用的ORDER BY阶段
1.4 逻辑查询处理的深入
内容
1.4.1 表运算符
1.4.2 OVER子句
1.4.3 集合运算符
1.5 总结
第2章 集合论和谓词逻辑
2.1 自然语言表述到数学表示的转换
2.1.1 严格定义(well-Definedness)
2.1.2 相等、恒等和同一性
2.1.3 数学命名约定
2.1.4 数字
2.1.5 上下文
2.1.6 函数、参数和变量
2.1.7 指令和算法
2.2 集合论
2.2.1 集合的标记方法
2.2.2 集合的严格定义
2.2.3 论域
2.2.4 真实性
2.2.5 罗素悖论(Russell s Paradox)
2.2.6 有序对、元组和笛卡尔积
2.2.7 空集
2.2.8 集合的特征函数
2.2.9 集合的基数(Cardinality)
2.2.10 顺序
2.2.11 集合运算符
2.2.12 集合论的推广
2.3 谓词逻辑
2.3.1 编程语言中的逻辑功能
2.3.2 命题和谓词
2.3.3 排中律
2.3.4 与、或、非运算
2.3.5 逻辑等价
2.3.6 逻辑蕴含
2.3.7 量化(Quantification)
2.3.8 替代和推广
2.4 关系
2.4.1 自反性、对称性和传递性
2.5
一个
实际的应用
2.6 总结
第3章 关系模型
3.1 关系模型简介
3.1.1 关系、元组和类型
3.1.2 关系模型:快速摘要
3.2 关系代数和关系计算
3.2.1 基本运算符
3.2.2 关系代数
3.2.3 Codd提出的8个原始关系运算符
3.2.4 关系演算
T-SQL支持
3.3 数据完整性
3.3.1 声明式约束
3.3.2 实施完整性的其他方法
3.4
数据库
正规化和其他设计主题
3.4.1 解决函数依赖的范式
3.4.2 更高级的范式
3.4.3 反规范化(Denormalization)
3.4.4 一般化和特殊化
3.5 总结
第4章 查询优化
4.1 本章用到的样本数据
4.2 优化方法论
4.2.1 分析实例级别的等待
4.2.2 关联等待和队列
4.2.3 确定行动方案
4.2.4 细化到
数据库
/文件级别
4.2.5 细化到进程级别
4.2.6 优化索引和查询
4.3 查询优化的工具
4.3.1 查询执行计划的缓存
4.3.2 清空缓存
4.3.3 动态管理对象
4.3.4 STATISTICS
4.3.5 测量查询的运行时间
4.3.6 分析执行计划
4.3.7 图形化的执行计划
4.3.8 提示(Hint)
4.3.9 跟踪/Profiler
4.3.10
数据库
引擎优化顾问
4.3.11 数据收集和管理数据仓库
4.3.12 使用SMO来复制统计信息
4.4 索引优化
4.4.1 表和索引的结构
4.4.2 索引访问方法
4.4.3 索引策略的分析
4.4.4 碎片
4.4.5 分区
4.5 准备样本数据
4.5.1 数据准备
4.5.2 TABLESAMPLE2
4.6 基于集合的方法和迭代/过程方法的比较,以及
一个
优化练习2
4.7 总结
第5章 算法和复杂性
5.1 你有
一个
1夸特的硬币吗?
5.1.1 如何从零钱罐中
取
回1夸特钱
5.1.2 有时零钱罐中没有1夸特的硬币
5.2 如何度量算法(How Algorithms Scale)
5.2.1 二次缩放(Quadratic Scaling)的
一个
例子
5.2.2 具有线性复杂度的算法
5.2.3 指数和超指数复杂度
5.2.4 次线性(sublinear)复杂度
5.2.5 常量复杂度
5.2.6 复杂度的技术定义
5.2.7 复杂度的比较
5.3 经典算法和算法策略
5.3.1 排序算法
5.3.2
字符串
查找
5.4
一个
实际的应用程序
5.4.1 识别测量数据的趋势
5.4.2 LISLP算法的复杂度
5.4.3 用T-SQL解决最长上升子序列的长度问题
5.5 总结
第6章 子查询、表表达式和排名函数
6.1 子查询
6.1.1 独立子查询
6.1.2 相关子查询
6.1.3 行为不当的子查询
6.1.4 不常用的谓词
6.2 表表达式(Table Expressions)
6.2.1 派生表
6.2.2 公用表表达式
6.3 分析排名函数
6.3.1 行号
6.3.2 排名和密集排名(Dense Rank)
6.3.3 组号(Tile Number)
6.4 数字辅助表
6.5 缺失范围和现有范围(也称为间断和孤岛)
6.5.1 缺失范围(间断)
6.5.2 现有范围(孤岛)
6.6 总结
第7章 联接和集合运算
7.1 联接
7.1.1 旧语法和新语法
7.1.2 基本联接类型
7.1.3 其他的联接分类
7.1.4 上一年度的滑动合计
7.1.5 联接算法
7.1.6 拆分元素
7.2 集合运算
7.2.1 UNION
7.2.2 EXCEPT
7.2.3 INTERSECT
7.2.4 集合运算的优先级
7.2.5 在集合运算中使用INTO
7.2.6 避开不支持的逻辑阶段
7.3 总结
第8章 数据聚合和透视
8.1 OVER 子句
8.2 决胜属性(Tiebreaker)
8.3 连续聚合
8.3.1 累积聚合(Cumulative Aggregation)
8.3.2 滑动聚合(Sliding Aggregation)
8.3.3 年初至今(YTD)
8.4 透视转换(Pivoting)35
8.4.1 透视转换属性35
8.4.2 关系除法
8.4.3 聚合数据
8.5 逆透视转换
8.6 自定义聚合
8.6.1 使用透视转换的自定义聚合
8.6.2 用户定义聚合函数(UDA,User Defined Aggregate)
8.6.3 专用解决方案
8.7 直方图(Histogram)
8.8 分组因子
8.9 分组集
8.9.1 样例数据
8.9.2 GROUPING SETS从属子句
8.9.3 CUBE从属子句
8.9.4 ROLLUP从属子句
8.9.5 分组集代数
8.9.6 GROUPING_ID函数
8.9.7 保存分组集
8.9.8 排序
8.10 总结
第9章 TOP和APPLY
9.1 SELECT TOP
9.1.1 TOP和确定性
9.1.2 TOP和输入表达式
9.1.3 TOP和修改
9.1.4 增强的TOP
9.2 APPLY
9.3 使用TOP和APPLY解决常见问题
9.3.1 每组中的TOP n
9.3.2 匹配当
前
值和
前
一个
值
9.3.3 分页
9.4 逻辑转换
9.5 总结
第10章 数据修改
10.1 插入数据
10.1.1 增强的VALUES子句
10.1.2 SELECT INTO
10.1.3 BULK行集提供程序
10.1.4 按最小方式记录日志的操作
10.1.5 INSERT EXEC
10.1.6 序列机制45
10.2 删除数据
10.2.1 TRUNCATE与DELETE
10.2.2 删除包含重复数据的行
10.2.3 基于联结的DELETE
10.3 更新数据
10.3.1 基于联结的UPDATE
10.3.3 更新大值数据类型
10.3.3 用SELECT和UPDATE语句进行赋值
10.4 合并数据
10.4.1 MERGE语句基础
10.4.2 额外增加
一个
谓词
10.4.3 多个WHEN子句
10.4.4 WHEN NOT MATCHED BY SOURCE子句
10.4.5 MERGE Values
10.4.6 MERGE与触发器
10.5 OUTPUT子句
10.6 总结
第11章 查询分区表
11.1 在SQL Server中进行分区
11.1.1 分区视图
11.1.2 分区表
11.2 总结
第12章 图、树、层次结构和递归查询
12.1 术语
12.1.1 图
12.1.2 树
12.1.3 层次结构
12.2 应用场景
12.2.1 员工组织图
12.2.2 材料清单(BOM)
12.2.3 道路系统
12.3 迭代/递归
12.3.1 下属
12.3.2 祖先
12.3.3 带有路径枚举的子图/子树
12.3.4 排序
12.3.5 环
12.4 具体化路径
12.4.1 维护数据
12.4.2 查询
12.5 使用HIERARCHYID数据类型的具体化路径5
12.5.1 维护数据
12.5.2 查询
12.5.3 使用HIERARCHYID的其他方面
12.6 嵌套集合
12.6.1 分配左值和右值
12.6.2 查询
12.7 传递闭包(Transitive Closure)
12.7.1 有向无环图
12.7.2 无向有环图
12.8 总结
在SQL Server中删除
字符串
中
第一次
出现
的
字符
,使用到charindex函数获
取
字符
第一次
出现
的位置索引,再使用STUFF函数替换掉指定位置的
字符
,如下所示:
--目的:删除替换
字符串
中
第一次
出现
的指定
字符
,eg:CMCS-004-1-->CMCS004-1
--1.查找指定
字符
在
字符串
中
第一次
出现
的位置索引,使用函数charindex(指定
字符
,查找
字符串
),结果:5
select charindex('-','CMCS-004-1')
--2.删除指定位置
字符
,结果:CMCS004-1
如果想要在 Microsoft SQL Server 中查找某个
字符
在
字符串
中第 N 次
出现
的位置,可以使用 CHARINDEX 函数。该函数接受三个参数:
要查找的
字符
(必需)
要搜索的
字符串
(必需)
开始搜索的位置(可选)
它会返回所查找
字符
在
字符串
中的位置,如果
字符
不存在,则返回 0。
举个例子,如果你想查找
字符串
'abcdef' 中
字符
'c' 第二次
出现
的位置,可以使用以下查询:
SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方式的用法。
先建立
一个
表,并添加一些数据来进行演示:
CREATE TABLE t_student(
Id INT NOT NULL,
Name NVARCHAR (10) NULL,
Age TINYINT NULL,
School NVARCHAR(20) NULL,
Class NVARCHAR(10) NULL,
Score FLOAT NULL,
CONSTRAINT [PK_Student_Id] PRIMARY KEY CLUSTERED(Id)
INSERT INTO t_student VALUES(1,'张小红',8,'育才小学','一班',92)
INSERT INTO t_student VALUES(2,'王丽丽',8,'育才小学','一班',90)
INSERT INTO t_student VALUES(3,'张燕',7,'云华小学','二班',86)
INSERT INTO t_student VALUES(4,'刘华',6,'云华小学','二班',85)
一、EXEC
EXEC命令可以执行
一个
存储过程也可以执行
一个
动态SQL语句。先来看看怎么执行存储过程:
新建
一个
存储过程 SP_GetStudent ,返回 成绩大于90 分的学生:
CREATE PROCEDURE [dbo].[Sp_GetStudent]
@Score FLOAT,
@Nums INT OUTPUT
BEGIN
SET NOCOUNT ON;
SELECT * FROM t_student WHERE Score >=@Score
SELECT @Nums=COUNT(1) FROM t_student WHERE Score >=@Score
IF(@Nums>0)
RETURN 1
RETURN 0
该存储过程涉及了 查询操作、返回值和输出参数,我们来看用EXEC 命令如何调用:
DECLARE @return_value int,
@OutNums int
EXEC @return_value = [dbo].[Sp_GetStudent]
@Score = 90,
@Nums = @OutNums OUTPUT
SELECT @OutNums as N'大于90分的人数'
SELECT '返回值' = @return_value
执行结果:
我们发现EXEC 执行存储过程和我们平时程序执行
一个
方法是几乎一样的,返回值参数 直接就可以等于存储过程的执行后的返回值,输出参数 在后面需要增加 OUTPUT 关键字。
执行存储过程不是重点,重点是执行动态sql语句,同样看一下例子:
DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT;
SET @TableName = 't_Student';
SET @Score = 90;
SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10))
EXEC (@sql);
执行结果:
注意:在执行拼接SQL 语句的时候,的EXEC括号中只允许包含
一个
字符串
变量,但是可以串联多个变量,如果我们直接执行这个SQL语句:
--这是错误的调用
EXEC ('SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10)));
执行就会提示错误。但是这样就没有问题:
DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT
DECLARE @Sql2 NVARCHAR(MAX)
SET @TableName = 't_Student';
SET @Score = 90;
SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName)
SET @Sql2=' WHERE Score >= '+CAST(@Score AS NVARCHAR(10))
EXEC (@sql+@sql2)
EXEC 执行拼接sql语句的时候不支持 嵌入式参数,如下:
DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX)
SET @IN_Score = 90
SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score'
EXEC (@sql)
通过上面的代码发现,EXEC 执行拼接的SQL语句的时候,不支持内嵌参数,包括输入参数和输出参数。有的时候我们想把得到的count(*)传出来,用EXEC是不好办到的。接下来,再来看看SP_EXECUTESQL的使用:
二、SP_EXECUTESQL:
SP_EXECUTESQL 是在 SQL 2005中引入的新的系统存储过程,也是用来处理动态SQL 语句的。它比EXEC 更加灵活,首先也执行一下
第一次
的拼接SQL语句:
DECLARE @TableName NVARCHAR(50),@Sql NVARCHAR(MAX),@Score INT;
SET @TableName = 't_Student';
SET @Score = 90;
SET @sql = 'SELECT * FROM '+QUOTENAME(@TableName) +'WHERE Score >= '+CAST(@Score AS NVARCHAR(10))
EXEC SP_EXECUTESQL @sql --注意这里没有了()
执行结果:
SP_EXECUTESQL 支持内嵌参数:
先来看一下SP_EXECUTESQL的语法:
sp_executesql [ @stmt = ] stmt
{, [@params=] N'@parameter_name data_type [ OUT | OUTPUT ][,...n]' }
{, [ @param1 = ] 'value1' [ ,...n ] }
[ @stmt = ] stmt 包含 Transact-SQL 语句或批处理的 Unicode
字符串
。stmt 必须是 Unicode 常量或 Unicode 变量。不允许使用更复杂的 Unicode 表达式(例如使用 + 运算符连接两个
字符串
)。不允许使用
字符
常量。如果指定了 Unicode 常量,则必须使用 N 作为
前
缀。例如,Unicode 常量 N'sp_who' 是有效的,但是
字符
常量 'sp_who' 则无效。
字符串
的大小仅受可用
数据库
服务器内存限制。在 64 位服务器中,
字符串
大小限制为 2 GB,即 nvarchar(max) 的最大大小。stmt 中包含的每个参数在 @params 参数定义列表和参数值列表中均必须有对应项
[ @params = ] N'@parameter_namedata_type[ ,... n ] ' 包含 stmt 中嵌入的所有参数定义的
字符串
。
字符串
必须是 Unicode 常量或 Unicode 变量。每个参数定义由参数名称和数据类型组成。n 是表示附加参数定义的占位符。在 stmt 中指定的每个参数必须在 @params 中定义。如果 stmt 中的 Transact-SQL 语句或批处理不包含参数,则不需要 @params。该参数的默认值为 NULL。
[ @param1 = ] 'value1'
参数
字符串
中定义的
第一个
参数的值。该值可以是 Unicode 常量,也可以是 Unicode 变量。必须为 stmt 中包含的每个参数提供参数值。如果 stmt 中的 Transact-SQL 语句或批处理没有参数,则不需要这些值。
[ OUT | OUTPUT ]
指示参数是输出参数。除非是公共语言运行 (CLR) 过程,否则 text、ntext 和 image 参数均可用作 OUTPUT 参数。使用 OUTPUT 关键字的输出参数可以为游标占位符,CLR 过程除外。
n 附加参数值的占位符。这些值只能为常量或变量,不能是很复杂的表达式(例如函数)或使用运算符生成的表达式。
返回代码值 :
0(成功)或非零(失败) 结果集:从生成 SQL
字符串
的所有 SQL 语句返回结果集
看不懂没有关系,通过例子就会非常明白的,依旧还执行上面的 SQL 语句:
DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX)
SET @IN_Score = 90
SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score'
EXEC SP_EXECUTESQL @sql,N'@Nums INT OUT,@Score INT',@OUT_Nums OUTPUT,@IN_Score
SELECT @OUT_Nums AS '人数'
执行结果:
需要注意的是:
1、要求动态Sql和动态Sql参数列表必须是NVARCHAR
2、动态Sql的参数列表与外部提供值的参数列表顺序必需一致
3、一旦使用了 '@name = value' 形式之后,所有后续的参数就必须以 '@name = value' 的形式传递,比如:
DECLARE @OUT_Nums INT,@IN_Score INT,@Sql NVARCHAR(MAX)
SET @IN_Score = 90
SET @sql = 'SELECT @Nums=COUNT(1) FROM t_student WHERE Score >= @Score'
EXEC SP_EXECUTESQL @stmt=@sql,@params=N'@Nums INT OUT,@Score INT',@Nums=@OUT_Nums OUTPUT,@Score=@IN_Score
SELECT @OUT_Nums AS '人数'
通过上面的例子已经很清晰的表明了,在执行动态SQL 语句的时候,EXEC 和 SP_EXECUTESQL 的区别了,来总结一下:
1、 性能:
官方描述:sp_executesql stmt 参数中的 Transact-SQL 语句或批处理在执行 sp_executesql 语句时才编译。随后,将编译 stmt 中的
内容
,并将其作为执行计划运行。该执行计划独立于名为 sp_executesql 的批处理的执行计划。sp_executesql 批处理不能引用调用 sp_executesql 的批处理中声明的变量。sp_executesql 批处理中的本地游标或变量对调用 sp_executesql 的批处理是不可见的。对
数据库
上下文所做的更改只在 sp_executesql 语句结束
前
有效。如果只更改了语句中的参数值,则 sp_executesql 可用来代替存储过程多次执行 Transact-SQL 语句。因为 Transact-SQL 语句本身保持不变,仅参数值发生变化,所以 SQL Server 查询优化器可能重复使用首次执行时所生成的执行计划。
说通俗一点就是:如果用 EXEC 执行一条动态 SQL 语句,由于每次传入的参数不一样,所以每次生成的 @sql 就不一样,这样每执行一次SQL SERVER 就必须重新将要执行的动态 Sql 重新编译一次 。但是SP_EXECUTESQL 则不一样,由于将数值参数化,要执行的动态 Sql 永远不会变化,只是传入的参数的值在变化,那每次执行的时候就不用重新编译,速度和效率自然有所提升。
2、从上面的例子我们已经能够看出 SP_EXECUTESQL 命令比 EXEC 命令更灵活,因为它提供
一个
接口,该接口及支持输入参数也支持输出参数。
3、EXEC 执行纯动态SQL,执行时可能无法使用预编译的执行计划,关键是不安全,可以导致 SQL 注入 ,而 SP_EXECUTESQL 执行参数化动态 SQL ,执行时能使用预编译的执行计划,而且保存存储过程时就可以确定可以使用的预编译的执行计划,而且最重要的是“安全”,天然免疫SQL 注入
作者:Rising Sun
出处:http://www.cnblogs.com/lxblog/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
1、--ASCII返回
字符串
的首字母的ASCII编码
selectASCII('ame')
selectASCII(xingming)fromxuesheng--查询语句中的格式
select*fromhahawhereASCII(name)>200--查询表中ASCII码大于
2、--CHAE将ASCII码转换...
记住防忘:
select 生产批次号,substring(E.生产批次号, charindex('-', E.生产批次号)+1,5) pc,
charindex('-', E.生产批次号,charindex('-', E.生产批次号,charindex('-', E.生产批次号)+1)+1)-(charindex('-', E.生产批次号)+1 ) kk,
case when charindex('-', E.生产批次号,charindex('-', E.生产批次号,charindex('-', E.生产批
Sqlserver
存储过程、函数中
字符串
分割并提
取
第n个值
sqlserver
存储过程中或函数中根据某个特定
符号
截
取
字符串
,并获
取
指定顺序的值,废话不多说直接上代码。@Str 为
字符串
,@s固定分隔符,@i 获
取
分割后第几个数。
ALTER FUNCTION [dbo].[Fun_split]
@Str NVARCHAR(MAX),
@s NVARCHAR(2),
@i int
RETURNS NVARCHAR(MAX)
BEGIN
DECLARE @Start INT;