Fra*_*ohn 1 powershell invoke-sqlcmd
使用 invoke-sqlcmd 将行插入表时发生了一个奇怪的错误。如果执行一次,整个脚本可以完美运行,但是如果我第二次运行它,它会失败并显示错误消息:Get-ChildItem:无法调用方法。提供程序不支持使用过滤器。我测试了代码并注释掉了 invoke-sqlcmd 行,并且可以多次运行它而没有任何错误。我将 invoke-sqlcmd 放在一个函数中,但它仍然出错,并且在第一次成功运行后,它也会在 PS 命令行中失败。
Clear-Host
$ErrorActionPreference = 'Stop'
function Update-SQL
{
invoke-sqlcmd -query $strSQLInsert -server SXLSV-LEAPDBD1 -database DTCS_DV
}
$files = Get-ChildItem '\\pcslog1011\dtcs\ContractEmailNotes\' -Filter '*.txt' | Where-Object {$_.LastWriteTime -ge '08/22/2016 00:00:00' -and $_.LastWriteTime -le '08/22/2016 23:59:59'} | sort-object -Descending
for ($i=0; $i -lt $files.Count; $i++)
{
$SNAC_CNTR_ID = $files[$i].BaseName.Substring(0,6)
$SNAC_MODIFIED = '{0:yyyy-MM-dd HH:mm:ss}' -f ($files[$i].LastWriteTime)
$reader = [System.IO.File]::OpenText($files[$i].FullName)
$lineCnt = 0
$SNAC_ACTION = ''
for()
{
$lineCnt += 1
$line = $reader.ReadLine()
if ($line -eq $null) {break}
if ($lineCnt -eq 4)
{
if ($line.Contains('AMENDED') -eq $True)
{
$SNAC_ACTION = 'AMENDED'
}
elseif ($line.Contains('DEAL CHANGED') -eq $True)
{
$SNAC_ACTION = 'CHANGED'
}
else
{
$SNAC_ACTION = 'NEW'
}
}
}
$reader.Close()
write-host $SNAC_CNTR_ID $SNAC_MODIFIED $SNAC_ACTION
$strSQLInsert = "INSERT INTO CQT_CONTRACT_SOX_NAC_LIST (SNAC_CNTR_ID, SNAC_MODIFIED, SNAC_ACTION, SNAC_UPDATED_BY, SNAC_UPDATED_ON) VALUES ('" + $SNAC_CNTR_ID + "', '" + $SNAC_MODIFIED + "', '" + $SNAC_ACTION + "', Default, Default)"
Update-SQL $strSQLInsert
}
exit
Run Code Online (Sandbox Code Playgroud)
小智 5
我知道这是一个相当古老的线程,但我遇到了一个类似的问题,导致我进入了这个页面。以下是为我解释和解决问题的链接。
PowerShell Invoke-Sqlcmd 切换到 sqlps 会话
卡在 Powershell sqlserver 中
默认情况下,SQLPS 提供程序不识别 UNC 路径。您可以使用特定的文件系统提供程序作为 UNC 路径的前缀:
Get-ChildItem Microsoft.PowerShell.Core\FileSystem::\\pcslog1011\dtcs\ContractEmailNotes\
-Filter '*.txt'
Run Code Online (Sandbox Code Playgroud)
或者在 SQLPS 模块加载后将您的工作目录切换回默认值,方法是将其添加到脚本的顶部:
Push-Location
Import-Module SQLPS -DisableNameChecking
Pop-Location
Run Code Online (Sandbox Code Playgroud)
问题似乎是由于 PowerShell 将工作目录从默认值切换到 SQLPS 提供程序的工作目录以及 SQLPS 提供程序无法识别 UNC 路径的组合(没有一些鼓励)。
因此,正常的 PowerShell 提示符如下所示:
PS C:\Users\foobar>
Run Code Online (Sandbox Code Playgroud)
这反而看起来像提示,当你在SQLPS供应商的目录结构如下工作(更多这意味着什么这里):
PS SQLSERVER:\>
Run Code Online (Sandbox Code Playgroud)
无论如何,脚本第一次调用 Get-ChildItem 时,很可能是从默认 PowerShell 工作目录的上下文中调用的(其中 UNC 路径可以理解)。但是,调用 Invoke-Sqlcmd 会加载 SQLPS 模块,该模块将工作目录更改为无法识别 UNC 路径的提供程序的工作目录。因此,下次调用 Get-ChildItem 时,它是从提供程序的目录结构中调用的,从而引发错误。该问题实际上与过滤器支持无关。
其他人发现的两种方法是在 UNC 路径前面加上文件系统提供程序,以便 SQLPS 可以解析它(源):
Get-ChildItem Microsoft.PowerShell.Core\FileSystem::\\pcslog1011\dtcs\ContractEmailNotes\ -Filter '*.txt'
Run Code Online (Sandbox Code Playgroud)
或者在 SQLPS 模块加载后切换回默认工作目录。这可能最好通过在脚本开头显式加载 SQLPS 提供程序并在前后添加 Push/Pop-Location cmdlet(不需要对原始脚本进行其他更改)来完成。
Push-Location
Import-Module SQLPS -DisableNameChecking
Pop-Location
Run Code Online (Sandbox Code Playgroud)
最后要注意两点。首先,我在大约 100 台不同操作系统版本、补丁级别和 PowerShell 版本的服务器上运行了我的代码。我只在一些运行 PowerShell 5.1 的服务器上看到过这个问题。其他 5.1 服务器没问题。
其次,这整个事件显然可以通过简单地使用应该替换 SQLPS 的较新的 SQLServer 提供程序来避免。
| 归档时间: |
|
| 查看次数: |
4154 次 |
| 最近记录: |