为什么我无法连接到一个SQL Server 2012 LocalDB共享实例?

27

我正在尝试在我的 Windows 7 x64 计算机上设置 SQL Server 2012 LocalDB (RTM, x64) 共享实例,但似乎无法连接到共享实例。我为所有设置使用管理员命令提示符。这是我创建实例的方法:

sqllocaldb create MyInstance

会产生以下响应:

LocalDB instance "MyInstance" created with version 11.0.

到目前为止一切顺利。现在我要分享这个实例:

sqllocaldb share "MyInstance" "MySharedInstance"

导致以下结果:

Private LocalDB instance "MyInstance" shared with the shared name: "MySharedInstance".

看起来仍然很好。此时,我使用info命令得到以下输出:

.\MySharedInstance
MyInstance
v11.0

当使用管理员或非管理员命令提示符从所有者帐户(即管理员)连接到实例时,似乎可以正常工作。 但是,当我以普通用户身份登录(而不是Windows管理员)并尝试连接时,事情就会失控:

sqlcmd -S (localdb)\.\MySharedInstance

结果为:

Sqlcmd: Error: Microsoft SQL Server Native Client 11.0 : Named Pipes Provider: Could not open a connection to SQL Server [2]. .
Sqlcmd: Error: Microsoft SQL Server Native Client 11.0 : Login timeout expired.
Sqlcmd: Error: Microsoft SQL Server Native Client 11.0 : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online..

使用“-l”开关增加登录超时时间没有帮助。我可以连接到默认的v11.0实例,该实例没有共享。非管理员用户的info命令与上面相同,只是没有“MyInstance”,因为它是由管理员用户拥有的命名实例。以下命令(适用于管理员用户/实例所有者):

sqllocaldb info ".\MySharedInstance"

同样会导致错误:

Windows API call "FileTimeToSystemTime" returned error code: -2147024809.
所以问题是为什么我的非管理员用户无法连接到共享实例?这似乎违背了共享实例的整个目的。而且当我尝试查询有关共享实例的信息时,“sqllocaldb info”命令为什么会抛出错误?

Krzysztof,我删除了MyInstance,重新创建并重新共享它。结果与以前完全相同。我可以从所有者/管理员帐户连接,但无法从普通用户帐户连接。当我使用非管理员用户运行“sqllocaldb info .\MySharedInstance”时,我收到相同的Windows API调用错误。 - Cory McCarty
@KrzysztofKozielczyk,感谢您在这里的贡献。我希望你们能考虑在未来允许所有共享实例的用户自动启动。LocalDB似乎是Express的一个很好的替代品,用于分发/用户模式和Compact的性能和功能。但我想象不到只有我一个开发人员需要在Windows应用程序之间共享数据。也许完全共享实例不需要成为默认行为,但启用它的方法似乎是有意义的。 - Cory McCarty
@AaronBertrand 这就是我所说的注册表损坏,很抱歉没有表达清楚。似乎由于某种原因,我们无法解码从LocalDB拥有的注册表键读取的时间戳。删除并重新创建实例可以解决这个问题。 - Krzysztof Kozielczyk
@Krzysztof,在我的情况下,删除并重新创建实例并不能解决Windows API错误。 - Cory McCarty
只是一些进一步的信息:“在共享之后,非所有者用户使用共享名称连接到实例之前,需要重新启动实例。如果实例已经在运行,我们不会自动重启它,以免破坏已经运行的应用程序。”因此,我认为由设计者启动实例非常重要,但重新启动也可能是您需要执行的步骤。我仍然建议,如果您希望开发人员无需干预地使用 SQL Server,则适当的实例比 localdb 更合适。 - Aaron Bertrand
显示剩余26条评论
5个回答

25

另一次编辑

Cory,如果您安装了先前版本的SQL Server(例如2008),那么您使用的是该版本的sqlcmd。为了连接到LocalDb,您需要使用sqlcmd的SQL Server 2012版本。因此,您向用户提供的说明必须确保他们运行以下命令以使用SQL Server 2012版:

C:\Program Files\Microsoft SQL Server\110\Tools\Binn\sqlcmd -S "(localdb)\.\InstanceName"

这对我有效。我尚未验证仅安装了sqllocaldb.msi的用户是否可用此路径和sqlcmd的版本。很抱歉,我没有没有安装SQL Server 2012(或仅安装了早期版本)的裸机进行全面测试。但是,如果明确调用110版本的sqlcmd可以解决问题,请告诉我。

我认为您还可以指示用户更改其系统变量,以使110版本排在第一位(在我看来,这应该自动发生)。

FileTimeToSystemTime已被Krzysztof的其中一名同事确认为错误。因此,我不知道非所有者如何通过sqllocaldb连接的解决方法。但是,我已经证明了SSMS和sqlcmd都可以正常工作,因此我希望这可以让您更接近运行。

编辑

您需要将任何非所有者用户添加到实例中,例如:CREATE LOGIN [MyDomain\OtherUser] FROM WINDOWS;,并授予任何适当的权限。在我的测试中,登录失败并生成了错误的错误消息(“FileTimeToSystemTime”错误消息是一个错误)。您还需要GRANT CONNECT。一旦您执行此操作,第二个用户将能够使用此连接(我尝试的唯一连接)使用管理工具进行连接。

(localdb)\.\MySharedInstance

但是从sqlcmd,无论我如何尝试连接,仍然会出现错误:

sqlcmd -S "(localdb)\.\MySharedInstance"
sqlcmd -S ".\MySharedInstance"
sqlcmd -S "(localdb)\MySharedInstance"
sqlcmd -S "GREENHORNET\MySharedInstance"
sqlcmd -S ".\LOCALDB#SH04FF8A"
sqlcmd -S "GREENHORNET\LOCALDB#SH04FF8A"

所有的yield:

HResult 0xFFFFFFFF,Level 16,State 1 SQL Server Network Interfaces:

Error Locating Server/Instance Specified [xFFFFFFFF].

Sqlcmd: Error: Microsoft SQL Server Native Client 10.0:建立到SQL Server的连接时发生了与网络或特定实例相关的错误。找不到服务器或无法访问。检查实例名称是否正确并检查是否配置了允许远程连接的SQL Server。有关更多信息,请参阅SQL Server Books Online。

Sqlcmd: Error: Microsoft SQL Server Native Client 10.0:登录超时。

尽管我已经验证了该实例设置为接受远程连接。因此,sqlcmd必须通过其他方式运行。

至于sqllocaldb exe,它如何遵循任何逻辑?我可以通过info看到该实例存在,当我尝试停止它时,我得到一个正确的错误消息,当我尝试启动它时,我会收到一个“已经”开始的消息,但我不能连接它?

enter image description here

因此,在短期内,除非您需要sqlcmd访问权限,否则我建议二次用户使用SSMS(在授予足够权限后)进行操作,并希望Krzysztof能提供有关其他项目的更多信息。


关于4.0.2更新,来自http://connect.microsoft.com/SQLServer/feedback/details/723737/smo-cant-connect-to-localdb-instances

我们明确决定不在LocalDB安装程序中包括.NET Framework 4.0.2。安装.NET Framework更新将增加LocalDB安装程序的大小并导致可能需要重新启动计算机。由于LocalDB是独立于.NET构建的,因此我们认为对每个LocalDB安装都应该承担这样的成本。未来的.NET版本(包括现在正在CTP中的.NET 4.5)将支持LocalDB。一些开发人员还可能选择加入ODBC、PHP驱动程序/PDO,以及将来可能包括JDBC。这些开发人员不会对更新.NET感兴趣。


9

正如原帖所建议的那样,这不像预期的那么简单,但最终我还是能够通过命名管道连接。

通过命名管道连接到 LocalDB 实例


很奇怪,我在使用默认的 MSSQLLocalDB 实例时遇到了同样的问题,通过实例管道名称连接成功了(在删除了 C:\Users<me>\ 目录下之前存在的数据库 MDF 和 LDF 文件后)。 - Lars Kemmann

1

本回答假设删除该实例是可以的。
即:您的所有数据将被删除,但这没有问题。

我遇到了同样的问题,在升级我的SSMS之后。

sqllocaldb i
.\MyCustomInstance

sqllocaldb d
LocalDb instance ".\MyCustomInstance" does not exist!

sqllocaldb i .\MyCustomInstance
Windows API call "FileTimeToSystemTime" returned error code: -2147024809.

为了摆脱冒犯的实例,我不得不创建另一个MyCustomInstance,我想这将覆盖已有的内容,现在你可以删除它。
sqllocaldb c MyCustomInstance
LocalDB instance "MyCustomInstance" created with version 11.0.
sqllocaldb d .\MyCustomInstance
LocalDB instance ".\Octopus" deleted.

然后,启动实例并共享它。 首先要启动实例。

sqllocaldb s MyCustomInstance
LocalDB instance "MyCustomInstance" started.
sqllocaldb h MyCustomInstance MyCustomInstance
Private LocalDB instance "MyCustomInstance" shared with the shared name: "MyCustomInstance".

现在,当你需要连接时,你需要连接到(localdb)\.\MyCustomInstance

0

安装完整的.NET Framework 4.5.2或更高版本,然后重新启动,您应该能够使用以下方式连接:

sqlcmd -S (localdb)\.\MySharedInstance

我发现当机器重新启动时,命名管道会生成一个新的哈希值,但命名共享实例将在重新启动后保持。

需要注意的是,在重新启动之前它是无法工作的。


-4

问题在于你需要引用数据库名称:

sqlcmd -S "(localdb)\.\MySharedInstance"

1
我认为这不是答案;一旦我使用了正确版本的sqlcmd(即随Sql Server 2012提供的版本),我就不需要引用。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接