惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Help Net Security
Help Net Security
G
Google Developers Blog
雷峰网
雷峰网
WordPress大学
WordPress大学
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
AWS News Blog
AWS News Blog
F
Full Disclosure
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
U
Unit 42
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
C
Cisco Blogs
博客园 - 司徒正美
Project Zero
Project Zero
L
LINUX DO - 热门话题
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
Scott Helme
Scott Helme
A
About on SuperTechFans
Hugging Face - Blog
Hugging Face - Blog
S
Securelist
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
G
GRAHAM CLULEY
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyberwarzone
Cyberwarzone
MongoDB | Blog
MongoDB | Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
T
Threatpost
Recorded Future
Recorded Future
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
The Register - Security
The Register - Security
S
Security Archives - TechRepublic
博客园 - Franky
N
News | PayPal Newsroom
Simon Willison's Weblog
Simon Willison's Weblog
S
SegmentFault 最新的问题
W
WeLiveSecurity
A
Arctic Wolf
B
Blog

博客园 - 马啸西风

SQL Server 2008之XML数据存储 SQL Server 2008之托管代码 SQL Server 2008之触发器 SQL Server 2008之约束 SQL Server 2008之用户自定义函数 SQL Server 2008之错误处理 SQL Server 2008之创建高并发应用程序 SQL Server 2008之合并数据和表传递 SQL Server 2008之通过非聚集索引提高性能 SQL Server 2008之读取查询计划 SQL Server 2008之表结构实现 SQL Server 2008之索引设计 SQL Server 2008之视图的设计和实现 SQL Server 2008之表的设计和实现 SQL Server 2008之数据类型 启用Application library caching时,将多个不同步的程序集打包到一个ZIP包中的问题 垃圾收集导致的概率性发生的bug DataGridView中下拉列表框的实现 C#之集合
SQL Server 2008之存储过程的设计和实现
马啸西风 · 2012-12-22 · via 博客园 - 马啸西风
  1. 共有两类基本的system stored procedure
  • system stored procedureT-SQL语言写的,在master数据库中提供的,大部分使用的是sp_前缀,在其他数据库中使用的时候,不需要指定master数据库作为他们的名称的一部分,典型应用于管理任务
  • system extended stored procedure:非托管代码写的(主要是C++),通过DLL提供的,大部分使用的是xp_前缀,用来扩展无法使用T-SQL完成的任务

还可以创建用户自定义的extended stored procedure,然后附加到SQL Server上,现在已经被遗弃,因为extended stored procedure是在SQL Server的内存空间上执行的,这不是执行代码的安全位置,现在推荐使用的是Managed code stored procedures

  1. 以下三类语句不允许在存储过程中使用:
  • 创建其他对象,包括AGGREGATERULEDEFAULTSCHEMAFUNCTIONTRIGGERPROCEDUREVIEW(这四个还不允许ALTER
  • 修改和查询计划相关的SET选项,包括PARSEONLYSHOWPLAN_ALLSHOWPLAN_TEXTSHOWPLAN_XML
  • 通过USE语句修改数据库上下文,可以通过使用数据库名称的方式引用另外一个数据库中的对象,但是不允许使用USE databasename语句切换数据库上下文
  1. 创建存储过程需要当前数据库的CREATE PROCEDURE权限和存储过程所属的schemaALTER权限,使用存储过程时必须保证数据库连接的设置和创建存储过程时是一致的,比如QUOTED_IDENTIFIERANSI_NULLS;创建存储过程时如果名称使用了#前缀,表示是一个临时对象,将被创建在tempdb中,服务器重启后将被删除;使用BEGIN...END不是必须的,但这是好的编程实践
  1. 创建存储过程时,使用two-part name引用对象,非常重要,如果仅仅使用了表的名称,没有指定schema名称的话,SQL Server首先查找默认schema,如果没有找到的话,就查找dbo schema,这最小化查询计划被重用的可能,因为直到执行存储过程时,才可以确定引用了哪个schema下的表,如果指定了two-part name的话,避免了引用表的歧义性,最大化SQL Server重用查询计划的可能
  2. 如果创建存储过程时,仅仅提供了存储过程名称的话,SQL Server视图在默认的schema下创建存储过程,存错过程创建位置基于执行的用户的默认schema行为是脆弱的
  3. 执行存储过程时,如果只指定了存储过程名称的话,SQL Server会依次在下面位置依次进行查找:
  • 如果存储过程名称以sp_开头的话(用户存储过程不建议这么做),在master数据库的sys schema下查找
  • 在执行存储过程的用户的默认shema下查找
  • 当前数据库的dbo schema下查找
  1. 修改存储过程时,不可以修改存储过程类型,比如不能将使用T-SQL创建的存储过程修改为托管代码的存储过程;数据库连接设置将使用修改时的设置,而不是最初创建存储过程时的设置,因此保证修改和创建时的设置一致非常重要;修改时必须提供创建时使用的所有选项(比如WITH ENCRYPTION),否则这些选项都不会被保留
  2. 删除存储过程时需要存储过程所属的schemaALTER权限或者存储过程本身的CONTROL权限,删除extended stored procedure使用sp_dropextendedproc
  3. 以前版本SQL Server使用sp_depends返回对象之间的依赖关系,这个存储过程有问题不能返回完整信息;现在使用sys.sql_expression_dependencies,每个依赖关系是一行,sys.dm_sql_referenced_entities每个被其他实体引用的实体是一行,sys.dm_sql_referencing_entities每个引用其他实体的实体是一行
  4. 创建存储过程的guidelines
  • 在存储过程中使用two-part name,尽量指定全名称
  • 保持SET选项的一致性
  • 名称一致性,采用统一的命名规范,不要使用sp_前缀,这些存储过程是用来定义系统存储过程的
  • 使用@@nestlevel查看当前的嵌套层级,最大值是32,在一个存储过程中调用另外一个存储过程就是一次嵌套
  • 保证每个存储过程完成一个任务
  1. 使用WITH ENCRYPTION加密存储过程,不过这里的加密的缺点和视图加密是一样的,不是很健壮,有很多第三方工具都可以破解,不建议使用
  2. 用户自定义函数不能指定输出参数,每个存储过程都会返回一个整型值,默认是0,用来表示结果值或者状态码,也可以返回业务逻辑相关值,但是应该使用输出参数表示业务逻辑相关值
  1. 存储过程的输出参数都有@前缀,数据类型,并且还可以指定默认值,执行存储过程时,既可以按顺序指定参数值,也可以通过名称指定参数值;最好在存储过程最开始处验证输入参数的合法性;输出参数要求类似于输入参数,在定义和使用输出参数时都必须显式指定OUTPUT关键字
  1. 为存储过程生成的执行计划大部分情况下是被重用的,这通常都是期望的行为;但是对于不同的参数集合来说有些存储过程可能需要完全不同的执行计划,这类问题称为parameter sniffing,解决办法如下:
  • 在定义存储过程时,添加WITH RECOMPILE选项,这样每次执行时,存储过程都会被重新编译
  • 调用sp_recompile系统存储过程时,对于传递的存储过程都将被标记为非法的,在下次执行时都将被重新编译,也可以向这个存储过程传递表或者视图的名称,这样凡是引用该对象的执行计划都会被重新编译
  • 可以在执行时,指定WITH RECOMPILE选项,这样将重新编译执行计划,但是不会存储生成的执行计划
  • OPTIMIZE FOR,这是一个查询提示选项,允许你在编译查询时为参数指定值,不管实际执行时参数值是什么
  1. 执行上下文就是执行存储过程的安全上下文,用来建立权限标识,由login tokenuser token表示,一个安全token包括如下内容:
  • 一个服务器或者数据库的principal作为主标识
  • 一或多个principals作为次要标识
  • 0或多个身份认证器
  • 主要和次要标识的特权和权限
  1. Login token:由SQL Server服务实例验证,包括主标识和次要标识,关于服务器级别的许可和任何数据库级别的许可,主标识就是登录本身,次要标识包括从rulesgroups继承来的权限
  2. User token:由特定数据库验证,包括关于数据库级别权限的主标识和次要标识,主标识就是数据库用户本身,次要标识就是从数据库roles继承来的许可,User token不能包括服务器角色成员,不鼓励赋予服务器级别许可
  3. EXECUTE AS语句用来设置存储过程的执行上下文,用来重写默认的安全上下文;支持显式模拟,使用单独的EXECUTE AS语句,还支持隐式模拟,在modules上使用EXECUTE AS语句,为了在另外一个用户上执行,必须拥有在那个用户上的IMPERSONATE权限
  4. EXECUTE AS LOGIN或者在服务器范围上的module使用EXECUTE AS语句,其范围是服务器级别的,即切换上下文后,模拟登录的用户拥有的权限的资源都可以访问;EXECUTE AS USER或者在数据库级别module上使用EXECUTE AS语句,意味着引用超出数据库范围外的对象都将返回错误
  5. sys.login_token系统视图展示所有login相关的token,包括login本身以及用户所属角色的tokensys.user_token系统视图展示用户相关的token

发表于 2012-12-22 23:25  马啸西风  阅读(1856)  评论()    收藏  举报

Powered By 博客园