【问题标题】:Write-SqlTableData fails with ConnectionToServerFailed halfway throughWrite-SqlTableData 中途出现 ConnectionToServerFailed 失败
【发布时间】:2021-07-13 16:44:22
【问题描述】:

我有一个 powershell 脚本,它在三个地方使用Write-SqlTableData(来自 SqlServer 模块)将 PSCustomObjects 写入(已经存在的)数据库表,如下所示:

# Note that for some reason, PSCustomObjects created by Select-Object don't always work well with 
# Write-SqlTableData, whereas "[PSCustomObject] @{ ... }" does.
$userDataRows = $users | Sort-Object id | ForEach-Object { [PSCustomObject] @{
    id = $_.id; 
    name = $_.name;
    employee_num = [string]($_.employee_num) }}

# Be careful with -Force, because the column types appear to be based on the *first row only*, and if it contains 
# a $null value its corresponding column will be of type SQL_VARIANT.
$userDataRows | Write-SqlTableData -ServerInstance '.' -Database 'MyDB'-SchemaName 'Staging' -TableName 'User'

在我的开发机器上,即使导入大约 18000 行,这也没有问题。但是,在生产机器上,对Write-SqlTableData 的调用失败并出现以下错误:

Write-SqlTableData : Failed to connect to server ..
At D:\Scripts\MyScript.ps1:155 char:25
+ ... eDataRows | Write-SqlTableData -ServerInstance '.' -Database 'MyDB' ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (.:String) [Write-SqlTableData], ConnectionFailureException
    + FullyQualifiedErrorId : ConnectionToServerFailed,Microsoft.SqlServer.Management.PowerShell.WriteSqlTableData

奇怪的是,它并不总是在同一点失败 - 通常在导入第三组数据时会失败,但偶尔会在第二组数据时失败。此外,通常会插入一些行,但它们的数量会有所不同:有时是 99,有时是 141...

谁能告诉我为什么在导入过程中出现“无法连接到服务器”?

编辑:总结一下我在一些 cmets 中的回答:不涉及网络,Dev 和 Prod 机器使用相同的 SQL Server 版本,并且不涉及多线程。此外,脚本失败太快而无法超时。

【问题讨论】:

  • 网络连接不好?
  • 这段代码在哪里执行?在你的开发盒上,我猜你有一个本地 SQL Epxress 什么的?您还应该在 QA 环境中进行测试,其中您有另一个 SQL Server,类似于 prod(甚至从 Prod 复制),然后在与现实生活类似的上下文中运行您的代码。这将帮助您找到错误的原因。
  • 我会尝试更改 SQLSERVER 超时值并在此模块中更改更改超时
  • SQL Server 日志中是否有错误?有很多服务器端问题可能导致从 powershell 断开连接。内存或磁盘等资源耗尽是很常见的。 Write-SqlTableData -Verbose 会给你额外的输出吗?
  • 你没有在你的例子中展示它,但看起来多线程这个命令也几乎总是会给你这个错误(可能不适用,但仔细检查你可能使用的任何工具使用)

标签: sql sql-server powershell


【解决方案1】:

解决了!长话短说,我现在使用-InputData 参数调用Write-SqlTableData,而不是通过管道向它传递数据。

也就是说,改变 $userDataRows | Write-SqlTableData ...

进入

Write-SqlTableData -InputData $userDataRows ...

...似乎解决了我的问题。此外,现在插入 18000 行需要 2 秒而不是 3.5 分钟。

这背后的原因很可能是,将 Write-SqlTableData 调用更改为使用 -InputData 意味着它会一次获得所有 18000 个 PSCustomObject,并使其能够以批处理方式执行其插入操作。这样可以避免“无法连接到服务器”错误并提供更好的性能。

我已经写了完整的解释here

【讨论】:

    猜你喜欢
    • 2020-01-18
    • 2016-11-03
    • 1970-01-01
    • 2021-08-24
    • 2012-08-19
    • 2018-02-24
    • 1970-01-01
    • 2020-01-24
    • 2015-04-24
    相关资源
    最近更新 更多