sp_checkreswords [<user_name_param>]
<user_name_param>
是当前数据库中用户的名称。如果提供 <user_name_param>,则 sp_checkreswords 将只检查指定用户拥有的对象。
如果 sp_checkreswords 在 master 数据库中执行,则显示结果:
1> /* executed in the master database */
2> sp_checkreswords
Reserved Words Used as Database Object Names for Database master
Upgrade renames sysobjects.schema to sysobjects.schemacnt.
Owner
------------------------------
dbo
Table Reserved Word Column Names
------------------------------ ------------------------------
authorization cascade
Object Type Reserved Word Object Names
------------------------------ ------------------------------
rule constraint
stored procedure check
user table arith_overflow
user table authorization
-------------------------------------------------------------
-------------------------------------------------------------
Owner
------------------------------
lemur
Table Reserved Word Column Names
------------------------------ ------------------------------
key close
Table Reserved Word Index Names
------------------------------ ------------------------------
key isolation
Object Type Reserved Word Object Names
------------------------------ ------------------------------
default isolation
rule level
stored procedure mirror
user table key
Reserved Word Datatype Names
------------------------------
identity
-------------------------------------------------------------
-------------------------------------------------------------
Database-wide Objects
---------------------
Reserved Word User Names
------------------------------
at
identity
Reserved Word Login Names
------------------------------
at
identity
Reserved Word as Database Names
------------------------------
work
Reserved Word as Language Names
------------------------------
national
Reserved Word as Server Names
------------------------------
mirror
primary
Reserved Word ServerNetNames
--------------------------------
mirror
primary
如果 sp_checkreswords 在用户数据库 user_db 中执行,则显示结果:
1> /* executed in the user database, user_db */
2> sp_checkreswords
Reserved Words Used as Database Object Names for Database user_db
Upgrade renames sysobjects schema to sysobjects.schemacnt.
Owner
------------------------------
tamarin
Table Reserved Word Column Names
------------------------------ ------------------------------
cursor current
endtran current
key identity
key varying
schema primary
schema references
schema role
schema some
schema user
schema work
Table Reserved Word Index Names
------------------------------ ------------------------------
key double
Object Type Reserved Word Object Names
------------------------------ ------------------------------
default escape
rule fetch
stored procedure foreign
user table cursor
user table key
user table schema
view endtran
-------------------------------------------------------------
-------------------------------------------------------------
Database-wide Objects
---------------------
Found no reserved words used as names for database-wide objects.
sp_checkreswords 报告保留字的现有对象名称。除非使用分隔标识符,否则 Transact-SQL 不允许将任何命令语法某一部分的字词用作标识符。保留字是 SQL 语法的构成元素,当用作命令的一部分时,它们具有特殊含义。例如,在 10.0 以前版本的 SQL Server 中,您可以具有一个名为 work 的表,并使用以下查询选择该表的数据:
select * from work
在 SQL Server 版本 10.0 中,work 是命令 commit work 的一部分,它是新增的保留字。在版本 10.0 或更高版本中发出相同的 select 语句会导致语法错误。sp_checkreswords 将查找会导致这些问题的标识符。
sp_checkreswords 也会查找使用 set quoted_identifier 选项创建的、用作标识符的保留字。
在升级到新版本的 SAP ASE 之前或紧接在升级之后使用 sp_checkreswords。有关在执行升级前安装和运行此过程的信息,请参见所用平台的安装文档。
在 master 数据库和每个用户数据库中运行 sp_checkreswords。另外,如果已将用户或对象添加到 model 和 sybsystemprocs 中,还应在这些数据库中运行此过程。
返回状态将指示找到的项目数。
如果提供了用户名,sp_checkreswords 将检查所有可由用户表、索引、视图、过程、触发器、规则、缺省值和用户定义的数据类型拥有的对象。它将报告所有是保留字的标识符。
如果当前数据库不是 master 数据库且没有提供用户名,则 sp_checkreswords 将检查上述所有对象,并在报告中为每个用户名提供一个单独的部分。它还检查 sysusers 和 syssegments 中是否有用户名和段名是保留字。如果已添加了对象、用户或用户定义的数据类型,则只需要检查 model 和 sybsystemprocs。
如果当前数据库是 master 且没有提供用户名,则 sp_checkreswords 将执行上述所有检查并检查 sysdatabases、syslogins、syscharsets、sysservers、sysremotelogins、sysdevices 和 syslanguages 中是否有保留字用作数据库、本地或远程登录、本地和远程服务器、字符集和语言的名称。
若要更改数据库的名称,请使用 sp_renamedb。该数据库必须处于单用户模式。删除并重新创建显式引用该数据库名称的所有过程、触发器和视图。有关详细信息,请参见 sp_renamedb。
如果 sp_checkreswords 报告有保留字用作标识符,则您可以执行以下两项操作之一:
使用 sp_rename、sp_renamedb 或更新系统表以更改标识符的名称。
如果保留字是表名、视图名或列名,则使用 set quoted_identifier on。如果您的大多数应用程序都使用存储过程,则可以删除,使用 set quoted_identifier on 重新创建这些过程并用引号将所有标识符引起来。所有用户都能够运行这些过程,而无需将 set quoted_identifier on 用于其会话。您可以使用 set quoted_identifier on,创建为表或列提供替代名称的视图,然后更改您的应用程序以引用这些视图。
以下示例提供了新保留字“key”、“level”和“work”的替代名称:
create view keyview
as
select lvl = "level", wrk = "work"
from "key"
set 命令的语法是:
set quoted_identifier on
如果未更改标识符或使用分隔标识符,则任何将保留字用作标识符的查询都会报告错误(通常是语法错误)。例如:
select level, work from key
Msg 156, Level 15, State 1:
Server 'rosie', Line 1:
Incorrect syntax near the keyword 'level'.
带引号的标识符选项是 SQL92 选项,许多支持其它 SAP ASE 功能的客户端产品可能不支持该选项。例如,不能在名称为保留字的表上使用 bcp。
在选择带引号的标识符选项之前,应使用所有将用于访问 SAP ASE 的工具对各种对象执行测试。使用 set quoted_identifier on 创建一个表名是保留字,各列名也是保留字的表。如果客户端产品生成 SQL 代码,则它就必须用双引号将标识符(如果它们是保留字)引起来,并用单引号将字符常量引起来。
如果过程、触发器和视图所依赖的对象已经更改了名称,则在名称更改之后,这些过程、触发器和视图可能会继续工作,但它们将在重新编译查询计划后停止工作。进行重新编译的原因有多种,并且不会通知用户。若要避免意外的功能损失,请在更改对象名之后立即在过程、触发器和视图中更改对象的名称。
不管是更改对象名还是使用分隔标识符,您必须更改包含保留字的所有存储过程、视图、触发器和应用程序。如果更改对象名,则必须更改标识符;如果使用分隔标识符,则必须添加 set quoted_identifier 选项和引号。
如果没有将过程、触发器、视图、规则和缺省值的文本保存在操作系统文件中,则可以使用 defncopy 将定义从服务器复制到文件中。请参见《实用程序指南》中的 defncopy。
如果更改 sp_checkreswords 所报告的项目的名称,则必须更改所有引用了使用保留字的对象的过程、触发器、视图和应用程序中的名称。
在更改标识符名称之前转储数据库。在更改标识符名称之后,运行 dbcc 以确定没有问题,然后再次转储数据库。
如果正在活动的生产数据库上更改标识符:
则应在系统最空闲时执行更改,以便将对用户的干扰降到最低的程度。
应通过查找使用特定标识符的所有 Open Client DB-Library 程序、窗口应用程序、存储过程、触发器和脚本进行精心准备。这样,您可以在源代码中进行所需的编辑,然后尽可能快地更改标识符并替换过程和代码。
过程 sp_depends 有助于查找使用表名和视图名的过程、视图和触发器。
系统过程 sp_rename 可以重命名表、索引、视图、过程、触发器、规则、缺省值、用户定义的数据类型和列。使用 sp_renamedb 可以重命名数据库。
可以用 sp_rename 更改的标识符的类型,和您需要在服务器和应用程序中进行的更改如下:
| 类型 | 即将进行的更改 |
|---|---|
| 表名称 | 删除所有引用该表的过程、触发器和视图,然后用新名称重新创建它们。使用 sp_depends 查找依赖于该表的对象。更改所有引用该表的应用程序或 SQL 源脚本以使用新表名。更改使用表名执行表级检查的 dbcc 脚本。 |
| 索引名称 | 删除任何创建或删除索引的存储过程,然后用新名称重新创建它们。更改所有创建或删除该索引的应用程序或 SQL 源脚本。更改使用索引名执行索引级检查的 dbcc 脚本。 |
| 视图名称 | 删除所有引用该视图的过程、触发器和视图,然后用新名称重新创建它们。使用 sp_depends 查找依赖于该视图的对象。更改所有引用该视图的应用程序或 SQL 源脚本以使用新视图名。 |
| 过程名称 | 删除引用该过程的所有过程和触发器,然后用新过程名称重新创建它们。更改执行该过程的所有应用程序或 SQL 源脚本以使用新名称。如果另一个服务器远程调用该过程,则更改远程服务器上的应用程序以使用新过程名称。 |
| 触发器名 – 更改所有创建该触发器的 SQL 源脚本。 | |
| 规则名 – 更改所有创建该规则的 SQL 源脚本。 |
|缺省名称|更改所有创建该缺省值的 SQL 源脚本。
|列名称|删除所有引用该列的过程、触发器和视图,然后用新列名重新创建它们。sp_depends 无法找到列名引用。以下查询显示引用了名为“key”的列的过程、触发器和视图的名称:
select distinct sysobjects.name
from sysobjects, syscomments
where sysobjects.id = syscomments.id
and syscomments.text like "%key%"
更改所有通过名称引用该列的应用程序和 SQL 源脚本。|
sp_rename "isolation", isolated
sp_rename "isolated.key", keyname
sp_depends <new_name>
若要更改用户名、登录名、设备名、远程服务器名、远程服务器用户名、段名、字符集名和语言名,需要确定是否可以删除对象或用户,然后重新添加或创建。
如果您无法删除对象或用户,则发出以下命令允许直接更新系统表:
sp_configure "allow updates to system tables", 1
仅系统安全员可设置 allow updates to system tables 配置参数。
直接更新系统表时产生的错误可能会在 SAP ASE 服务器中造成严重问题。确定是否可以删除对象或用户,然后重新创建它们:
| 标识符类型 | 为避免更新系统表而推荐的操作 |
|---|---|
| 用户名和登录名 | 若要更改没有对象的用户的名称:1. 在每个数据库中使用 sp_helprotect |
| 设备名 | 如果此设备已被完全分配,则无需在 create database 命令中使用其名称,因此可以保持该名称不变。 |
| 远程服务器名 | 除非远程服务器中有大量的远程登录名,否则应删除远程服务器(sp_dropserver),然后用新名称添加该服务器(sp_addserver)。 |
| 远程服务器登录名 | 使用 sp_dropremotelogin 删除远程登录,使用 sp_addremotelogin 以新名称添加该登录,然后用 grant 恢复用户执行过程的权限。 |
| 段名 | 在段上创建对象之后,很少会使用段名。 |
| 字符集名和语言名 | 只有当系统管理员用 sp_addlanguage 创建替代语言后,语言和字符集才会将保留字用作标识符。用 sp_droplanguage 删除该语言,然后用新名称添加它。 |
此表显示对这组标识符可能具有的依赖性。无论您选择的升级方法是删除再重新创建对象、使用分隔标识符还是对系统表执行直接更新,都请查看此表以了解可能的依赖性。
警告
直接更新系统表可能非常危险。您可能犯下严重的错误,使 SAP ASE 服务器无法运行或无法访问数据库中的对象。若要直接更新系统表,您应该在心平气和、精力集中,并且服务器上没有(或只有很少的)生产活动时进行。如果可能,请使用下表中介绍的替代方法。
更改标识符时的注意事项:
| 标识符 | 务必要 |
|---|---|
| 登录名 | 更改该用户在其每个数据库中的用户名。 |
| 用户名 | 删除、编辑和重新创建对该用户拥有的对象使用限定(<owner_name>.<object_name>)引用的所有过程、触发器和视图。更改使用限定对象名的所有应用程序和 SQL 源脚本以使用新用户名。您无需删除这些对象本身;sysusers 已按照存储用户标识(而不是用户名)的列链接到 sysobjects。 |
| 设备名 | 更改引用该设备名的所有 SQL 源脚本或应用程序以使用新名称。 |
| 远程服务器名 | 更改远程服务器上的名称。如果 sp_checkreswords 报告的名称是本地服务器的名称,则在发出或接收远程过程调用之前必须先重新启动服务器。 |
| 远程服务器网络名 | 在 interfaces 文件中更改服务器的名称。 |
| 远程服务器登录名 | 更改远程服务器上的名称。 |
| 段名 | 删除并重新创建所有在该段名上创建表或索引的过程。更改所有在段上创建对象的应用程序以使用新段名。 |
| 字符集名 | 无。 |
| 语言名 | 更改 master.dbo.syslanguages 和 master.dbo.syslogins。对 syslogins 的更新可能涉及多个行。另外,请更改本地化文件的名称。 |
该示例显示一个“安全的”用户名更新过程,在所有数据修改之前是一个 begin transaction 命令。系统安全员执行:
sp_configure "allow updates to system tables", 1
然后您可以执行:
begin transaction
update sysusers
set name = "workerbee"
where name = "work"
此时运行查询,检查以确保该命令只影响要更改的行。唯一可以影响多个行的标识符更改是更改 syslogins 中的 language 名称。如果查询影响了:
完成之后,系统安全员可以使用以下命令关闭 allow updates to system tables 配置参数:
sp_configure "allow updates to system tables", 0
警告
只更新每个用户定义的事务中单个数据库的系统表。不要在发出 begin transaction 命令后更新多个数据库中的表。这样的操作会使恢复极为困难。
下表显示了更改保留字时应该更新的系统表和列。以“master.dbo.”为前缀的表只能出现在 master 数据库中。所有其它表出现在 master 和用户数据库中。在尝试更新之前,请确保使用的是正确的数据库。您可以使用以下命令检查当前数据库名:
select db_name()
表 4:更改标识符时要更新的系统表列
| 标识符类型 | 要更新的表 | 列名 |
|---|---|---|
| 用户名 | sysusers | name |
| 登录名 | master.dbo.syslogins | name |
| 段名 | syssegments | name |
| 设备名 | sysdevices | name |
| 远程服务器名 | sysservers | srvname |
| 远程服务器网络名 | sysservers | srvnetname |
| 字符集名 | master.dbo.syscharsets | name |
| 语言名 | master.dbo.syslanguagesmaster.dbo.syslogins | namelanguage |
使用分隔标识符的注意事项。
1 可以将分隔标识符用于表名、列名和视图名。不能将分隔标识符用于其它对象名。
2 如果选择使用分隔标识符,则使用 set quoted_identifier on,然后删除并重新创建所有使用该标识符的过程、触发器和视图。编辑这些对象的文本,将保留字用双引号引起来,将所有字符串用单引号引起来。
下面的示例显示为使用分隔标识符而对查询进行的更改。此示例更新名为 work 的表,该表包括名为 key 和 level 的列。下面列出的是 10.0 以前版本的查询(它将字符文字用双引号引起来),以及为使用分隔标识符而对该查询进行编辑后的版本:
/* pre-release 10.0 version of query */
update work set level = "novice"
where key = "19-732"
/* 10.0 or later version of query, using
** the quoted identifier option
*/
update "work" set "level" = 'novice'
where "key" = '19-732'
3 必须对所有将保留字用作标识符的应用程序进行如下更改:
在以下示例中,此查询将导致错误消息:
set quoted_identifier on
select * from titles where title_id like "BU%"
正确的查询是:
select * from titles where title_id like 'BU%'
4 在分隔标识符生效时创建的存储过程可以在不打开该选项的情况下运行。(allow updates to system tables 选项的工作方式也是这样。)这意味着您可以打开带引号标识符模式,删除存储过程,编辑该过程以在用作标识符的保留字两边插入引号,然后重新创建该过程。所有用户无需使用 set quoted_identifier 即可执行该过程。