数据库教程25:SQL Server中xp_、sp_为前缀的存储过程及MSSQL的命名规范问题

1,807 阅读3分钟

这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战

首先指出一点,用户自定义的存储过程名称,千万不要以sp_、xp_开头

sp_、xp_前缀的存储过程

存储过程在创建时进行编译,这样后面每次执行都不需要重新编译,这样可以提高执行效率。并且将复杂的逻辑操作封装为存储过程,可以简化逻辑处理,很方便地和其他SQL事务一起执行。

在SQL Server中,常见默认提供的sp_、xp_开头的存储过程。

  • sp_sp_开头的表示系统存储过程。用来进行SQL Server的各项设定、取得信息、相关管理操作等。如sp_help就是取得指定对象的相关信息。

  • xp_xp_开头的表示扩展存储过程(Extended Stored Procedures)。用于提供操作系统级别的功能,编写服务器级别的程序或逻辑处理。也可以称为存储过程API。该功能将在最新版本中移除,不建议使用。可以使用CLR集成(CLR Integration)或分布式查询等新的更强大的技术替代实现所需的功能。

CLR Stored Procedures,CLR存储过程就是CLR集成技术中的一种。

SQL Server存储过程命名约定

SQL Server使用对象名称(object names)和架构名称(schema names)查找要使用的特定对象。比如一个表、存储过程、函数、视图等。

因此为各个对象提出标准的命名约定是一个很好的做法。

不要使用sp_前缀

"sp_"前缀不应作为命名约定。这是在master数据库中使用的标准命名约定。用来服务系统存储过程(system stored procedures)。

如果不指定对象所在的数据库,SQL Server将首先搜索master数据库,查看该对象是否存在,然后再搜索用户数据库。使用sp_前缀,将导致额外的时间开销和执行效率问题。

标准化前缀

除了sp_之外,可以使用下面几种:

  • usp_
  • sp
  • usp
  • proc_

使用哪种都可以,但上面的几种有助于区分对象,使其更易于管理。

对应的几个例子可以是:

  • usp_InsertPerson
  • spInsertPerson
  • uspInsertPerson
  • proc_InsertPerson

命名操作类型和对象名称

可以使用Insert、Delete、Update、Select、Get、Validate等相关的操作来命名。

然后是,指定对象名称,对象名称可以是真实的对象,如表;或者简单且有意义的处理名。

比如:

  • usp_InsertPerson - 插入新的人员记录
  • usp_GetAccountBalance - 获取账户余额
  • usp_GetOrderHistory - 返回订单列表

推荐遵循动词-名词约定。

架构名(Schema)

一个架构是一些对象的集合,类似一个容器。这种逻辑分组可以帮助区分不同的对象。

一些架构的示例:

  • HR.usp_GetPerson
  • HR.usp_InsertPerson
  • UTIL.usp_Get
  • UTIL.usp_GetLastBackupDate

使用CREATE SCHEMA命令创建一个新的架构。

如下,创建一个名为“HR”的新模式并将此模式授权给“DBO”。

CREATE SCHEMA [HumanResources] AUTHORIZATION [dbo];

组合

这样,一个完整的名称约定由一下部分组成:

  • Schema
  • Prefix
  • Action
  • Object

其他对象的命名约定

不要使用'tbl','sp_','xp_','dt_'等描述性前缀。它们有着特殊含义,首先会在master数据库中查找。

tbl前缀最早做为从Access导入SQL Server时表示的表,常称为"tibbling"

表名不要和它的某个列名一样。

-- 查找表名和列名相同的表
SELECT Thetable.Name FROM sys.columns cols
INNER JOIN sys.tables Thetable 
  ON Thetable.object_id = cols.object_id
  WHERE cols.NAME=Thetable.name

或者,查找列名中包含表名的冗余的表:

-- 查找列名中包含表名的表
SELECT TheTable.name AS TableName, TheColumn.name AS ColumnName
  FROM sys.tables AS TheTable
    INNER JOIN sys.columns AS TheColumn
      ON TheColumn.object_id = TheTable.object_id
  WHERE TheColumn.name LIKE '%' + TheTable.name + '%';

表名应尽量简短,因为在索引名、约束名、触发器名等名称中,通常要求包含表名。为避免冗余,表名也不应该包含集体名称,比如schema名。

-- 查找表名和架构名相同的表、视图等对象
SELECT name FROM sys.objects WHERE Object_Schema_Name(object_id) = name;

本篇主要参考文章已找不到,暂不列出参考文章。