无法在 32 位环境上加载程序集 MICROSOFT.SQLSERVER.BATCHPARSER

发布于 2025-01-13 23:10:51 字数 4239 浏览 2 评论 0原文

我在这里发布我的问题,希望有人能帮助我解决这个问题。

因此,我为我的一个客户开发了一个 PS 脚本,用于检索数据库表并将其作为 CSV 直接导出到 Blob 存储。我的脚本在 64 位环境中运行良好。但是,我无法在 32 位环境中运行它。我需要在32位环境中运行它,因为客户端使用的调度程序是32位工具。 就我而言,我已经尝试了在网上找到的关于这个主题的所有内容,但没有成功。

正如我上面所说,我的问题是我无法在 32 位环境中运行我的脚本。我放了展位环境的屏幕截图,以便您可以看到我所拥有的。

绿色方块是预期结果。黄色的是我遇到的错误。 蓝色方块显示了我下载的 SqlServer 模块(x86 和 64)。

我在 CMD SHELL 中也有同样的行为。

所以我的问题是: 有没有办法让这个脚本在 32 位环境下运行? 否则是否有办法强制 32 位 CMD SHELL 在 PowerShell 上打开 64 位会话?

这是完整的 PS SCript:

param (
    [String]$SourceServer="" ,
    [String]$SourceDatabase="" ,


    [String]$DestinationStorageAccountName = "",
    [String]$DestinationStorageAccountContainrerName= "",

    [String]$DBUser = "",
    [String]$DBUserPWD = ""
)

FUNCTION Write-ToBlobStorage{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][String]$ResultString,
        [Parameter(Mandatory)][String]$DestinationStorageAccountName,
        [Parameter(Mandatory)][String]$DestinationStorageAccountContainrerName,
        [Parameter(Mandatory)][String]$FileName
    )

    write-host "Clear existing identies to keep cache fresh"
    Clear-AzContext -force

    write-host "Authenticate using the Managed identity"
    $account = Connect-AzAccount -identity
    if(-not $account.Context.Subscription.Id)
    {
        write-error "Failed to authenticate with the Managed identity. Ensure VM has a Managed identity enabled and is assigned the correct IAM roles"
        return
    }

    write-host "Get storage context"
    $context = New-AZStorageContext  -StorageAccountName $DestinationStorageAccountName

    write-host "Get storage Container"
    $container=Get-AzStorageContainer -Name $DestinationStorageAccountContainrerName -Context $context

    write-host "Writing Result to storage"
    $content = [system.Text.Encoding]::UTF8.GetBytes($ResultString)

    $container.CloudBlobContainer.GetBlockBlobReference("$FileName.csv").UploadFromByteArray($content,0,$content.Length)

}


#Import-Module 'Az.KeyVault' -Force
#Import-Module -Name 'C:\Program Files\WindowsPowerShell\Modules\SqlServer' -Force
Import-Module -Name 'C:\Program Files (x86)\WindowsPowerShell\Modules\SqlServer' -Force


$TLS12Protocol = [System.Net.SecurityProtocolType] 'Ssl3 , Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $TLS12Protocol


$Query = "SELECT @@SERVERNAME"

$Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $SourceDatabase -Query $Query | ConvertTo-Csv -Delimiter '|' -NoTypeInformation

$ResultString = $Result -join "`r`n" 

Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAccountName $DestinationStorageAccountName -DestinationStorageAccountContainrerName $DestinationStorageAccountContainrerName -FileName "TMP_Flux"

write-host "--- ALL DONE---"

这是 32 位的错误:

Invoke-Sqlcmd : Could not load file or assembly 
'Microsoft.SqlServer.BatchParser, Version=15.100.0.0, Culture=neutral, 
PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot 
find the file specified.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:87 char:11
+ $Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $Sour ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-Sqlcmd], FileNotFoundEx 
   ception
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.SqlServ 
   er.Management.PowerShell.GetScriptCommand
 
Write-ToBlobStorage : Cannot bind argument to parameter 'ResultString' because 
it is an empty string.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:91 char:35
+ Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAc ...
+                                   ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Write-ToBlobStorage], Parameter 
   BindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAll 
   owed,Write-ToBlobStorage
 
--- ALL DONE---

这是 64 位的结果:

Clear existing identies to keep cache fresh
Authenticate using the Managed identity
Get storage context
Get storage Container
Writing Result to storage
--- ALL DONE---

非常感谢您的所有建议。

I'm posting my problem here, hoping someone may help me to figure the issue.

So, for one of my clients I've developed a PS script that retrieve a table for a database and export it as a CSV directly to a Blob Storage. My script works fine in a 64-Bit environment. However, I cannot run it in a 32-Bit environment. I need to run it in a 32-Bit environment because the scheduler used by the client is a 32-Bit tool.
On my side, I've tried every thing I've already found around the net on this subject with no luck.

My problem as I said above is that I fail to run my script on a 32-Bit environment. I'm putting a screenshot of booth environment so you can see what I'm having.

The Green square is the expected result. The Yellow one is the error I'm having.
The Blue squares shows booth SqlServer Modules I downloaded (x86 & 64).

I have the same behavior from a CMD SHELL.

So My questions are:
Is there anyway to make this script working on a 32-Bit environment?
Else Is there anyway to force a 32-BIT CMD SHELL to open a 64-Bit session on PowerShell ?

Here is the FUll PS SCript :

param (
    [String]$SourceServer="" ,
    [String]$SourceDatabase="" ,


    [String]$DestinationStorageAccountName = "",
    [String]$DestinationStorageAccountContainrerName= "",

    [String]$DBUser = "",
    [String]$DBUserPWD = ""
)

FUNCTION Write-ToBlobStorage{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][String]$ResultString,
        [Parameter(Mandatory)][String]$DestinationStorageAccountName,
        [Parameter(Mandatory)][String]$DestinationStorageAccountContainrerName,
        [Parameter(Mandatory)][String]$FileName
    )

    write-host "Clear existing identies to keep cache fresh"
    Clear-AzContext -force

    write-host "Authenticate using the Managed identity"
    $account = Connect-AzAccount -identity
    if(-not $account.Context.Subscription.Id)
    {
        write-error "Failed to authenticate with the Managed identity. Ensure VM has a Managed identity enabled and is assigned the correct IAM roles"
        return
    }

    write-host "Get storage context"
    $context = New-AZStorageContext  -StorageAccountName $DestinationStorageAccountName

    write-host "Get storage Container"
    $container=Get-AzStorageContainer -Name $DestinationStorageAccountContainrerName -Context $context

    write-host "Writing Result to storage"
    $content = [system.Text.Encoding]::UTF8.GetBytes($ResultString)

    $container.CloudBlobContainer.GetBlockBlobReference("$FileName.csv").UploadFromByteArray($content,0,$content.Length)

}


#Import-Module 'Az.KeyVault' -Force
#Import-Module -Name 'C:\Program Files\WindowsPowerShell\Modules\SqlServer' -Force
Import-Module -Name 'C:\Program Files (x86)\WindowsPowerShell\Modules\SqlServer' -Force


$TLS12Protocol = [System.Net.SecurityProtocolType] 'Ssl3 , Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $TLS12Protocol


$Query = "SELECT @@SERVERNAME"

$Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $SourceDatabase -Query $Query | ConvertTo-Csv -Delimiter '|' -NoTypeInformation

$ResultString = $Result -join "`r`n" 

Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAccountName $DestinationStorageAccountName -DestinationStorageAccountContainrerName $DestinationStorageAccountContainrerName -FileName "TMP_Flux"

write-host "--- ALL DONE---"

And Here is The error for the 32-Bit :

Invoke-Sqlcmd : Could not load file or assembly 
'Microsoft.SqlServer.BatchParser, Version=15.100.0.0, Culture=neutral, 
PublicKeyToken=89845dcd8080cc91' or one of its dependencies. The system cannot 
find the file specified.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:87 char:11
+ $Result = Invoke-Sqlcmd -ServerInstance $SourceServer -Database $Sour ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Invoke-Sqlcmd], FileNotFoundEx 
   ception
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.SqlServ 
   er.Management.PowerShell.GetScriptCommand
 
Write-ToBlobStorage : Cannot bind argument to parameter 'ResultString' because 
it is an empty string.
At C:\temp\ExportToBlobScript\ExportToBlob.ps1:91 char:35
+ Write-ToBlobStorage -ResultString $ResultString -DestinationStorageAc ...
+                                   ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Write-ToBlobStorage], Parameter 
   BindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAll 
   owed,Write-ToBlobStorage
 
--- ALL DONE---

And Here is the result for the 64-Bit:

Clear existing identies to keep cache fresh
Authenticate using the Managed identity
Get storage context
Get storage Container
Writing Result to storage
--- ALL DONE---

Many Thanks for all of you suggestions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没有把握。但由于您仅使用 Invoke-SqlCmd 来运行查询,因此您可以直接从 PowerShell 使用 ADO.NET 来消除对 SqlServer powershell 模块的依赖。 SQL Server 客户端库是 .NET 框架的一部分,因此它们可以在任何 Windows 机器上使用。所以像这样:

function Invoke-SqlCmd-Custom{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][String]$ServerInstance,
        [Parameter(Mandatory)][String]$Database,
        [Parameter(Mandatory)][String]$Query 
    )

    $con = new-object System.Data.SqlClient.SqlConnection
    $con.ConnectionString = "Server=$ServerInstance;Database=$Database;Integrated Security=true"
    try
    {
        $con.Open()
        $cmd = $con.CreateCommand()
        $cmd.CommandText = $Query 
        $dt = new-object System.Data.DataTable
        $rdr = $cmd.ExecuteReader()
        $dt.Load($rdr)
        return $dt.Rows
    }
    finally
    {
      $con.Close()
    }

}

Not sure. But since you're only using Invoke-SqlCmd to run a query, you can eliminate the dependence on the SqlServer powershell module by using ADO.NET directly from PowerShell. The SQL Server client libraries are part of the .NET framework, so they will be available on any Windows box. So something like:

function Invoke-SqlCmd-Custom{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)][String]$ServerInstance,
        [Parameter(Mandatory)][String]$Database,
        [Parameter(Mandatory)][String]$Query 
    )

    $con = new-object System.Data.SqlClient.SqlConnection
    $con.ConnectionString = "Server=$ServerInstance;Database=$Database;Integrated Security=true"
    try
    {
        $con.Open()
        $cmd = $con.CreateCommand()
        $cmd.CommandText = $Query 
        $dt = new-object System.Data.DataTable
        $rdr = $cmd.ExecuteReader()
        $dt.Load($rdr)
        return $dt.Rows
    }
    finally
    {
      $con.Close()
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文