SQL Server 2005 Express Edition 用户实例
Roger Wolter
适用于:
SQL Server 2005 Express Edition
**摘要:**本文介绍 SQL Server 2005 Express Edition 中的用户实例,以及如何使用它们来简化向 Visual Studio 项目添加数据库功能的操作。
您可以下载本文使用的 Microsoft Word 版本。
本页内容
简介
附加数据库文件
AttachDBFilename
用户实例
打开用户实例连接
SSEUtil
默认配置为关闭
从其他客户端连接到用户实例
用户实例限制
常见问题
分发和部署
RANU
转换用户实例数据库
小结
简介
新的 SQL Server 2005 Express Edition 的设计目标是实现与 Visual Studio 数据库设计功能更紧密的集成。Visual Studio 项目系统非常擅长管理组成项目的一组文件。要顺利地适应此工具集,必须将 SQL Server 数据库作为文件进行操作。幸运地,SQL Server 数据库是一个文件集合,因此将文件集合作为 Visual Studio 项目的一部分进行管理并不复杂。遗憾的是,在您的应用程序中将这些文件作为数据库进行连接并不如所愿的那样简单和自动化。用户实例功能使该操作变得更容易。
附加数据库文件
如果我们了解 Microsoft SQL Server 2005 中的用户实例是用来解决哪些问题的,就更容易理解这些实例。本节介绍如何将数据库文件附加到一个 SQL Server 数据库实例中,这是用户实例可以简化的操作之一。
本文提供两种 SQL Server 数据库文件类型(还有其他类型,但是对于我们而言,两种足以)。即数据 (.mdf) 文件和日志 (.log) 文件。
包含数据库数据的文件的扩展名为 .mdf,例如,AccountsReceivable.mdf 是一个数据文件。每个数据文件都有一个对应的日志文件,该日志文件包含事务日志。日志文件的扩展名为 .ldf。例如,数据库的日志文件被命名为 AccountsReceivable_log.ldf。
这两个文件彼此紧密耦合。数据库文件包含有关日志文件准确版本的信息。如果从备份恢复数据文件,但不恢复相同版本的日志文件,则数据库不会启动。当在项目中操作数据库文件时,将这两个文件作为一个匹配集非常重要。例如,如果还原到以前版本的 .mdf 文件,还必须还原到相同版本的 .ldf 文件。
在连接到 SQL Server 数据库之前,服务器必须知道这些数据库文件。服务器打开文件、验证版本、确保日志文件与数据库文件匹配,然后执行使数据库文件与日志文件同步所需的任何恢复操作。让运行 SQL Server 的服务器知道某个数据库文件的过程称为附加 数据库。如果 Sally 有一个需要通过企业服务器上的 SQL Server 访问的数据库文件,则她将 .mdf 文件和 .ldf 文件交给数据库管理员 (DBA)。DBA 将:
使用 CREATE DATABASE ... FOR ATTACH 命令将数据库文件附加到服务器。
在服务器上为 Sally 创建一个登录。
在数据库中为 Sally 的登录创建一个用户。
向该用户授予 Sally 运行其应用程序所需的权限。
如果这是一个重要的应用程序,这些工作就有意义;但如果 Sally 在自己的计算机上开发应用程序,这些努力就多余了。请注意,对于正在运行 SQL Server 实例的计算机而言,如果 Sally 是其中 Administrators 组的成员,则不需要后三个步骤。这是因为,管理员始终可以登录并拥有与该服务器连接的所有数据库的管理员权限。
AttachDBFilename
幸运地,SQL Server 客户端代码包括一个名为 AttachDBFilename 的选项,通过该选项,DBA 无需将数据库文件附加到服务器即可使用它们。当连接字符串中包括 AttachDBFilename 关键字时,指定的文件被附加到 SQL Server 实例,并且客户端连接到新附加的数据库。AttachDBFilename 选项的参数是要附加的文件名。以下是一个示例。
AttachDbFilename=|DataDirectory|\Database1.mdf;
|DataDirectory| 是打开连接的程序所在目录的快捷方式。要附加其他目录中的文件,必须提供该文件的完整路径。此例中的日志文件名为 Database1_log.ldf 并与数据库文件位于同一目录下。如果数据库文件已经附加到 SQL Server 实例,则向现有数据库打开该连接。
这是一个不错的选项,因为如果您是管理员,就可以通过在应用程序的连接字符串中指定文件名来附加并连接到一个数据库文件。许多开发人员在他们的系统上以管理员身份运行,因此,AttachDBFilename 可以为他们正常工作。问题在于,Microsoft 强烈建议“不要”以管理员身份运行,因为这样做可以减少病毒可能造成的危害数量。在这种情况下,我们需要的是一种方法,使得无需作为 Windows Administrators 组的成员就能使用 AttachDBFilename。解决方案是用户实例功能。
用户实例
我已经提及 SQL Server 实例好几次,但没有定义它们是什么。SQL Server 实例 是一个在服务器上运行的 SQL Server 可执行程序。每个实例都有一个名称,内存中的一个 sqlservr.exe 进程、缓冲区内存、它自己的系统数据库副本,以及它自己的一组用户数据库。例如,默认情况下,SQL Server Express 作为一个名为“SQLEXPRESS”的实例安装。通过在连接字符串中指定带有服务器名称的实例名,可以连接到已命名的实例。这就是在连接到本地 SQL Server Express 数据库时通常将“.\SQLEXPRESS”指定为服务器名的原因。点(.)意味着本地服务器,\SQLEXPRESS 指定了 SQLEXPRESS 命名实例。SQL Server 服务 (sqlservr.exe) 作为 Microsoft Windows 服务运行,并且在指定为 Windows 服务管理器中的服务帐户的用户上下文中执行。对于 SQL Server Express,该帐户默认为“NT AUTHORITY\NETWORK SERVICE”,在安装期间可以指定其他帐户。
SQL Server Express 通过支持用户实例来扩展 SQL Server 实例的概念。用户实例与普通实例类似,但它是在需要的时候创建,而普通实例是在安装期间创建的。用户实例的服务帐户是打开到数据库的 SQL Client 连接的 Windows 用户。换句话说,如果 Sally 打开一个到数据库文件的连接,该数据库文件在连接字符串中指定了 User Instance 选项,则该用户实例将 Sally 作为服务帐户。
在 SQL Client 连接字符串中设置 User Instance 选项后,会创建用户实例。以下是 Visual Basic 配置文件的一部分,显示了 User Instance 选项。
<connectionStrings> <add name="TestVB1.Settings.Database1ConnectionString" connectionString="Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\Database1.mdf; Integrated Security=True; User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings>
以下是连接字符串中需要注意的一些问题。
数据源为 .\SQLEXPRESS。用户实例由 SQL Server Express 父实例创建,因此初始连接必须指定父实例。
AttachDBFilename 用于指定要附加到用户实例的数据库。
Integrated Security 为 True。用户实例仅与集成安全性一起使用,带有用户名和密码的 SQL Server 用户不起作用。
提供程序名为 System.Data.SqlClient。User Instance 选项仅在 SqlClient 连接字符串上有效。
当包含该连接字符串的连接成功打开时,用户应用程序连接到一个以打开该连接的用户身份运行的 SQL Server Express 用户实例。该用户连接到“database1.mdf”文件中的数据库。如果 Sally 打开该连接,则用户实例运行,Sally 作为服务帐户。由于 Sally 是该实例的服务账户,因此 Sally 具有该用户实例连接的所有数据库的完全管理员权限,即使她不是 Windows 管理员。这就是即使 Sally 是普通用户,AttachDBFilename 选项也能运行的原因。
打开用户实例连接
当打开一个 User Instance 选项为 True 的连接时会发生什么?下列步骤描述用户第一次打开一个用户实例连接时发生的情况。
SQLClient 逻辑打开一个到 SQL Server Express 父实例(默认情况下是 .\SQLEXPRESS)的连接。
SQL Server Express 检测到已经设置了 User Instance 选项且该用户没有用户实例。
将 master 和 msdb 系统数据库文件复制到用户的目录下。在 Sally 的示例中,该目录为:
C:\Documents and Settings\Sally\Local Settings\Application
Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS
这些文件是从一个在安装父实例时创建的模板目录复制的。用户实例启动后,**tempdb**、日志和跟踪文件被写入这个相同的用户目录。
父实例模拟正在打开该连接的 Windows 用户,并且启动一个以该用户身份运行的 sqlservr.exe 副本。系统数据库的位置作为参数传递。生成实例的名称。例如: 69651E0A-5550-46。
为新实例创建一个命名管道数据库连接。该名称基于实例名。例如:
\\.\pipe\69651E0A-5550-46\tsql\query.
将 AttachDBFilename 参数中指定的数据库文件附加到新实例,并用该文件的完整路径命名该文件:
[C:\MYDBPROJECTS\TESTVB1\TESTVB1\DATABASE1.MDF]
命名管道的名称传回到正在打开连接的 SqlClient。
SqlClient 接收到该连接的名称后,关闭到父实例的连接。它使用返回的命名管道名打开一个到该用户实例的新连接。
一旦为特定用户创建了用户实例,就会保留系统数据库和命名管道。因此,在第一次连接后,后续连接就只需执行后两步操作了。
关闭到该实例的最后一个连接后,启动的 sqlservr.exe 进程还会继续运行一段时间。因此,如果打开其他连接,则不需要重新启动该进程。继续运行的时间长度是由 sp_configure 选项“用户实例超时”设置的。默认情况下,时间长度设为 60 分钟,但是您可以用 sp_configure 命令更改它。
SSEUtil
使用用户实例时必不可缺的一个工具是 SSEUtil。该工具打开一个用户实例并允许对该用户实例执行 SQL 命令。它还可以分离一个用户实例,以便您可以使用文件。还有许多其他可用的功能,而且每个版本的 SSEUtil 都变得更完善、功能更强大。您可以从 SQL Server Express Utility Web 站点下载。
可以用 SSEUtil 执行的一些操作如下所示:
附加和分离数据库。
运行 SQL 语句并执行 SQL 批处理文件。
列出并连接到子实例。
执行Checkpoint 命令并缩小数据库。
签署数据库。
默认配置为关闭
由于安全原因,默认情况下 SQL Server 2005 有几个功能是关闭的,以减少黑客可攻击的代码表面区域。随 SQL Server Express 一起安装了一个名为表面区域配置 (SAC) 的工具,它允许您配置这些选项。使用 SAC 工具更改配置会更改父实例的设置,但不会影响任何用户实例。这就允许每个实例只打开其应用程序需要的选项。
由于 SAC 工具不配置用户实例,因此必须重新使用我们熟悉的 SSEUtil 来进行该配置。用户实例中通常需要的唯一一个选项是“clr enabled”选项,如果应用程序包括 CLR 存储过程、触发器、用户定义的类型等,则需要该选项。下图显示如何打开“clr enabled”选项。
C:\SSEUtil>sseutil -c Console mode. Type 'help' for more information. 1> sp_configure 'clr enabled','1' 2> go Command completed successfully. 1> reconfigure 2> go Command completed successfully.
为了完整性,还有其他两个打开 OLE 自动化和 xp_cmdshell 的选项。不建议使用这两个选项。CLR 存储过程通常以更安全、更可靠的方式执行这些过程所执行的操作。如果您真的需要使用这些选项,下面显示如何使用 SSEUtil 打开它们。
C:\SSEUtil>sseutil -c Console mode. Type 'help' for more information. 1> sp_configure 'show advanced option', '1' 2> go Command completed successfully. 1> reconfigure 2> go Command completed successfully. 1> sp_configure 'xp_cmdshell', '1' 2> go Command completed successfully. 1> reconfigure 2> go Command completed successfully. 1> sp_configure 'Ole Automation Procedures', '1' 2> go Command completed successfully. 1> reconfigure 2> go Command completed successfully.
从其他客户端连接到用户实例
只能通过 Microsoft .NET Framework 应用程序中的 SqlClient 连接来创建用户实例并启动用户实例进程。然而,一旦用户实例运行,则通过打开到为该用户实例创建的命名管道的连接,任何可以连接到该命名管道的客户端都可以连接到该用户实例。命名管道的名称可以从父实例的 sys.dm_os_child_instances 视图中获得。使用以下语句。
SELECT owning_principal_name, instance_pipe_name FROM sys.dm_os_child_instances
图 1 显示典型 sys.dm_os_child_instances 视图的内容。
图 1
知道了命名管道的名称后,可以将 np: 放在它前面并在连接字符串中使用它。例如,下面是 SQLCMD.exe 会话中的一段内容。
C:\>sqlcmd -S np:\\.\pipe\69651E0A-5550-46\tsql\query 1> use [C:\MYDBPROJECTS\TESTVB1\TESTVB1\DATABASE1.MDF] 2> go Changed database context to 'C:\MYDBPROJECTS\TESTVB1\TESTVB1\DATABASE1.MDF'. 1> select * from test1 2> go Col1 Col2 Col3 ------ ---------- ----------------------- 1 Frank 2005-02-11 00:00:00.000 12 Sam 2001-03-21 00:00:00.000
这个命名管道是一个仅限于本地的命名管道,因此无法从远程客户端附加到用户实例。另外切记,仅当另一个使用 SqlClient 连接的应用程序在上一小时内启动了用户实例后才能直接附加到命名管道。
用户实例限制
独特的用户实例体系结构引入了一些功能限制,如下所示:
仅允许本地连接。
不能复制用户实例。
分布式查询对远程数据库不起作用。
用户实例仅在 SQL Server 2005 的 Express Edition 内运行。
常见问题
当数据库不按照我们习惯的方式工作时,用户实例体系结构有时会产生混淆。这些问题大多数都是关于附加到用户实例的数据库文件以及如何处理数据库文件的。以下是较为常见的问题。
用户实例无法附加到数据库,因为该用户没有所需的权限。用户实例在打开连接的用户上下文中执行,而不是以正常的 SQL Server 服务帐户执行。打开用户实例连接的用户必须根据连接字符串 AttachDbFilename 选项中指定的 .mdf 文件和 .ldf 文件具有写入权限。使用 Visual Web Designer 时会出现一个常见问题。应用程序从 Visual Studio 集成开发环境 (IDE) 连接到一个用户实例数据库,然后当 Web 页打开该数据库时,应用程序连接失败。当 ASP 页打开该数据库时,它通常作为 ASPNET 运行。如果 ASPNET 不具有对数据库文件的写入权限,则连接失败。
另一个常见问题是,当数据库附加到 SQL Server Express 实例后,您成功地打开了数据库文件,但是尝试从 Visual Studio IDE 打开它时失败。发生这种错误的原因可能是 SQL Server Express 实例正在作为“NT AUTHORITY\NETWORK SERVICE”运行,而 IDE 正在以您的身份运行。因此,权限可能不起作用。
该问题的另一种情况是,打开用户实例连接的用户具有对数据库文件的读取权限,但没有写入权限。在这种情况下,SQL Server 将数据库库作为一个 READ_ONLY 数据库进行附加。如果您收到一条消息,告诉您该数据库是以只读方式打开的,则需要更改数据库文件的权限。
用户实例的另一个主要问题是由于 SQL Server 以独占访问方式打开了数据库文件。这是必需的,因为 SQL Server 管理其内存中数据库数据的锁定。因此,如果多个 SQL Server 实例打开同一个文件,则有可能损坏数据。如果两个不同的用户实例使用同一个数据库文件,则一个实例必须先关闭该文件,然后另一个实例才能打开它。有两种常用的方法可以关闭数据库文件,如下所示。
用户实例数据库设置了 Auto Close 选项,这样如果 8 到 10 分钟内没有与数据库进行连接,就会关闭数据库和文件。该操作自动发生但会花费一些时间,尤其是为您的连接启用了连接池之后。
通过调用 sp_detach_db 将数据库和实例分离将关闭该文件。当 IDE 在用户实例之间切换时,Visual Studio 使用该方法确保数据库文件是关闭的。例如,您正在使用 IDE 设计一个支持数据的 Web 页。按 F5 键运行应用程序。IDE 分离数据库,这样 ASP.NET 就可以打开数据库文件。如果您让数据库附加到 IDE 并尝试从浏览器运行 ASP 页,由于 IDE 仍在使用该文件,则 ASP.NET 无法打开数据库。
分发和部署
用户实例的一个有吸引力的功能是,通过在应用程序代码中包括媒体上的数据库文件,可以分发数据库应用程序。如果将数据库文件复制到应用程序所在的目录,并在连接字符串的 AttachDbFilename 选项中使用 |DataDirectory|,那么只要安装了 SQL Server Express,无论将应用程序复制到何处,数据库都会起作用。如果用户还没有 SQL Server Express,您可以在应用程序中包括 SQL Server Express,或者您的用户可以从 Web 上下载。无需其他配置即可支持用户实例。
RANU
每个软件功能都需要一个很酷的缩写。已经采用了用户实例的逻辑缩写 UI,因此用户实例又称作RANU(Run As Normal User 的缩写)。正式名称是用户实例功能,但您经常会听到该功能被称作 RANU。
转换用户实例数据库
您可能希望将用户实例数据库更改到一个普通的 SQL Server 数据库中。这么做的主要原因是,您希望多个用户连接到该数据库或需要升级到另一个版本的 SQL Server,可能因为您碰到了性能或数据库大小的限制。虽然有多种方法可以实现该操作,但最简单的方法是使用 CREATE DATABASE ... FOR ATTACH 命令将数据库文件附加到普通的 SQL Server 实例。然后在连接字符串中删除 AttachDbFilename 和用户实例选项。切记当连接到自己的 SQL Server 实例时,您具有对附加到该实例的数据库的完全管理员权限。当更换到普通的 SQL Server 实例时,每个用户都必须有一个登录和数据库用户。必须授予数据库用户运行该应用程序所需的权限。
小结
SQL Server 2005 Express Edition 包括一个新的用户实例功能,该功能允许应用程序在指定存储数据库数据的文件名后打开一个数据库连接。即使正在打开连接的用户不是管理员,该功能也能运行。该功能简化了与 .NET 连接的数据库应用程序的创建和分发。
有关详细信息
https://www.microsoft.com/technet/prodtechnol/sql/default.mspx