如何使用 Invoke-Sqlcmd 连接到 SQL Server LocalDB?
Posted
技术标签:
【中文标题】如何使用 Invoke-Sqlcmd 连接到 SQL Server LocalDB?【英文标题】:How to connect to SQL Server LocalDB using Invoke-Sqlcmd? 【发布时间】:2013-06-09 14:04:27 【问题描述】:我有来自 SQLServer 2008 和 SQLServer 2012 的sqlcmd.exe
:
PS C:\> Get-Command sqlcmd.exe
Definition
----------
C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\SQLCMD.EXE
通过修改$env:PATH
,我强制使用 SQL Server 2012 中的sqlcmd.exe
:
PS C:\> $env:PATH = ($env:PATH -split ";" | Where-Object $_ -notlike "*\Microsoft SQL Server\100\*" ) -join ";"
PS C:\> Get-Command sqlcmd.exe
Definition
----------
C:\Program Files\Microsoft SQL Server\110\Tools\Binn\SQLCMD.EXE
LocalDB 的默认实例已启动并运行,并归当前用户所有:
PS C:\> sqllocaldb i v11.0
Name: v11.0
Version: 11.0.2318.0
Shared name:
Owner: DOMAIN\me
Auto-create: Yes
State: Running
Last start time: 12/06/13 18:17:57
Instance pipe name: np:\\.\pipe\LOCALDB#08EDBEF0\tsql\query
现在,我可以使用sqlcmd.exe
对(localdb)\v11.0
执行命令
PS C:\> sqlcmd.exe -S "(localdb)\v11.0" -Q "select 1"
-----------
1
但是当我尝试与Invoke-Sqlcmd
相同时,我得到一个连接错误:
PS C:\> Import-Module sqlps
PS C:\> Invoke-Sqlcmd -ServerInstance "(localdb)\v11.0" -Query "select 1"
Invoke-Sqlcmd : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
我该怎么做才能使Invoke-Sqlcmd
连接到(localdb)\v11.0
?
【问题讨论】:
有趣的是,它在 PowerGUI 中工作,而在 powershell 中失败。我使用 ProcessMonitor 跟踪了两个进程,并且都加载了正确的模块(C:\Program Files (x86)\Microsoft SQL Server\110\Tools\PowerShell\Modules\SQLPS\SQLPS.PSD1)。两者都能够连接到“常规”实例,例如 SQLEXPRESS。 您对此有正确的执行策略吗?我建议将执行策略更改为 ByPass 或 Unrestricted。Set-ExecutionPolicy Bypass
请考虑将其中一个答案标记为首选解决方案。
【参考方案1】:
这是从其他几个来源获得的,目前看来有效。
JBs Powershell
和
How can I run PowerShell with the .NET 4 runtime?
让 PowerShell 和 LocalDB 发挥出色的另一种方法是让 PowerShell 了解 DOTNET 4.0.3。这可以通过在 C:\Windows\System32\WindowsPowerShell\v1.0 中创建一个名为“powershell.exe.config”的文件来完成。该文件应包含以下内容:
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
请注意,这不是官方支持的 PowerShell 使用方式,因此它可能会破坏其他内容...
【讨论】:
【参考方案2】:更新
来自SqlServer
模块的Invoke-Sqlcmd
支持LocalDB:
Invoke-Sqlcmd -ServerInstance "(localdb)\v11.0" -Query "select 1"
Invoke-Sqlcmd -ConnectionString "Server=(localdb)\v11.0; Integrated Security=True" -Query "select 1"
# both will work
【讨论】:
【参考方案3】:据我所知sqlcmd.exe
使用包含所有信息的连接字符串,而Invoke-Sqlcmd
将这些信息分解为不同的参数。因此,您可能需要将(localdb)
和v11.0
拆分为ServerInstance
、Database
和ComputerName
。或者您可以改用ConnectionString
参数。
现在,我不熟悉您对 localdb
的使用,因此它处理该问题的方式可能有些奇怪……或其他什么。
【讨论】:
【参考方案4】:我最近在工作中一直在这样做,并且在连接到本地数据库时遇到了一些麻烦。为了让它工作,我运行了以下代码;
C:\> Import-Module sqlps -DisableNameChecking
SQLSERVER\:> cd ".\SQL\$(hostname)"
SQLSERVER\:> Invoke-Sqlcmd -Username "user" -Password "pass" -Database "databasename" -Query "foobar"
这对我有用,我能够查询数据库。显然,将用户名、密码和数据库参数详细信息更改为 SQL 实例上调用的数据库名称。
【讨论】:
FWIW,这是一个本地数据库,而不是“localdb”(即:一个是完整的 sql 安装,另一个是 localdb)。【参考方案5】:这是在不利条件下适用于我的代码(请参阅代码后面的我的 cmets)。我怀疑更简单的代码可能会在更常见的环境中工作,但我没有深入研究它。
实例管道在几分钟后超时。如果您可以使用 (localdb)\instanceName 进行连接,您会更好,因为这些连接似乎不会超时。
function Get-InstancePipeName ([string] $localDbName)
while (!($pipeName = ((sqllocaldb info $localDbName) -match 'instance pipe name').Split(':', 2)[1].Trim()))
sqllocaldb start $localDbName | Out-Null
return $pipeName
$scsb = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
$scsb.psbase.DataSource = Get-InstancePipeName localDbName # <== put your db name here
$sc = New-Object System.Data.SqlClient.SqlConnection $scsb.ConnectionString
$smoSc = New-Object Microsoft.SqlServer.Management.Common.ServerConnection $sc
$smoSvr = New-Object Microsoft.SqlServer.Management.Smo.Server $smoSc
Invoke-Sqlcmd -ServerInstance $smoSvr -Query 'select 1'
由于目前我无法控制的原因,运行此程序的执行环境异常。这是一个具有不完整会话上下文的远程执行环境。此外,我不得不重新定义 USERPROFILE 以解决其他一些问题。
[稍后编辑:我最近发现a way to extend the timeout - 我必须在第二个 sp_configure 之后添加一个 RECONFIGURE 并(按照建议)停止并启动 localdb 以使其生效)]
【讨论】:
【参考方案6】:我猜invoke-sqlcmd 不知道“(localdb)”是什么。尝试改用 localhost。
【讨论】:
对我不起作用。一定是别的东西,但不知道是什么。 invoke-sqlcmd 似乎不支持localdb。您必须了解,invoke-sqlcmd 不仅仅是调用 sqlcmd 并传入参数。它是自己的 sqlcmd 版本,并不完全支持 sqlcmd 所做的一切。至少现在还没有。 谢谢@RobertLDavis,我知道这是一个完全不同的版本。但是我不明白为什么它可以在 PowerGUI 中工作而在 powershell 中失败。 PowerGUI 可能在实际运行命令之前对其进行了处理。这完全取决于他们实际运行 PowerShell 命令的方式。以上是关于如何使用 Invoke-Sqlcmd 连接到 SQL Server LocalDB?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 WSL 连接到本地 Windows SQL Server 实例?
无法从 C# 通过 Wallet 连接到 Oracle DB