无法从 ExecuteNonQuery 针对 MS SQL 服务器从 PowerShell 脚本执行的插入中取回计数
Not Getting Back a Count from an Insert Executed by ExecuteNonQuery Against MS SQL Server from PowerShell script
以下代码执行成功的 BULK INSERT,但未 return 受影响的行数。当我执行 'SELECT count(*) ...' 确认计数时,已插入数百万行。我怀疑溢出错误是问题的一部分。为什么受影响的行数未达到 return?关于如何获得计数的任何想法?我还有其他几个类似的例程,它们总是 return 计数。
代码
try {
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = "Persist Security Info=False;Integrated Security=true;Initial Catalog=$($file_info.database);server=$($file_info.db_server_instance)"
$Command.CommandTimeout = 18000 # 5 hours
$Command.Connection.Open()
try {
$bulkinsert_sql = "BULK INSERT $($file_info.database).$($file_info.owner).$($file_info.table) FROM '$load_file_path' with (ERRORFILE='$load_file_error_path', MAXERRORS=$($file_info.dbload_error_max), TABLOCK, FIELDTERMINATOR='\t')"
$Command.CommandText = $bulkinsert_sql
$loaded_cnt=$Command.ExecuteNonQuery()
write-host "$loaded_cnt ROWS LOADED"
} catch [System.Data.SqlClient.SqlException] {
$_ | select -expandproperty invocationinfo | Format-List Line, PositionMessage -force
write-host $_.Exception.ToString() -foregroundcolor "red"
$ErrorActionPreference = "Continue"
}
# set error preference back
$ErrorActionPreference = "stop"
} catch [System.Data.SqlClient.SqlException] {
$_ | select -expandproperty invocationinfo | Format-List Line, PositionMessage -force
write-host $_.Exception.ToString() -foregroundcolor "red"
$ErrorActionPreference = "stop"
} finally {
if ($Command.Connection -eq 'Open') {
$Command.Connection.Close()
}
}
已捕获错误消息
System.Data.SqlClient.SqlException (0x80131904): Bulk load data conversion error (truncation) for row 1714271, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (truncation) for row 1714272, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (truncation) for row 2083378, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (overflow) for row 4633809, column 82 (TF_ME_TOT_DEDUCTIONS).
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,
TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean&
usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at CallSite.Target(Closure , CallSite , Object )
ClientConnectionId:ba9e07ac-1bc4-4c59-8a0a-167d7b281644
Error Number:4863,State:1,Class:16
Why is the rows affected count failing to return? Any ideas of how to get the count?
ExecuteNonQuery 不是 运行 查询的 "lowest level" 方法。它对 SQL 服务器可能 return 的信息做了一些简化假设。
当 运行 来自客户端的查询 SQL 服务器可以 return 错误消息、行计数消息和结果集的任意组合。但是为了简化正常情况,SqlClient 在看到错误消息时会抛出 SqlException,因此 ExecuteNonQuery 甚至 return(更不用说 return 行数了)。
如果您希望 ExecuteNonQuery return,您可以将所有错误消息重定向到事件处理程序,并使用 SqlConnection.FireInfoMessageEventOnUserErrors.
抑制 .NET 异常抛出行为
以下代码执行成功的 BULK INSERT,但未 return 受影响的行数。当我执行 'SELECT count(*) ...' 确认计数时,已插入数百万行。我怀疑溢出错误是问题的一部分。为什么受影响的行数未达到 return?关于如何获得计数的任何想法?我还有其他几个类似的例程,它们总是 return 计数。
代码
try {
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = "Persist Security Info=False;Integrated Security=true;Initial Catalog=$($file_info.database);server=$($file_info.db_server_instance)"
$Command.CommandTimeout = 18000 # 5 hours
$Command.Connection.Open()
try {
$bulkinsert_sql = "BULK INSERT $($file_info.database).$($file_info.owner).$($file_info.table) FROM '$load_file_path' with (ERRORFILE='$load_file_error_path', MAXERRORS=$($file_info.dbload_error_max), TABLOCK, FIELDTERMINATOR='\t')"
$Command.CommandText = $bulkinsert_sql
$loaded_cnt=$Command.ExecuteNonQuery()
write-host "$loaded_cnt ROWS LOADED"
} catch [System.Data.SqlClient.SqlException] {
$_ | select -expandproperty invocationinfo | Format-List Line, PositionMessage -force
write-host $_.Exception.ToString() -foregroundcolor "red"
$ErrorActionPreference = "Continue"
}
# set error preference back
$ErrorActionPreference = "stop"
} catch [System.Data.SqlClient.SqlException] {
$_ | select -expandproperty invocationinfo | Format-List Line, PositionMessage -force
write-host $_.Exception.ToString() -foregroundcolor "red"
$ErrorActionPreference = "stop"
} finally {
if ($Command.Connection -eq 'Open') {
$Command.Connection.Close()
}
}
已捕获错误消息
System.Data.SqlClient.SqlException (0x80131904): Bulk load data conversion error (truncation) for row 1714271, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (truncation) for row 1714272, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (truncation) for row 2083378, column 72 (PROVIDER_NAME1).
Bulk load data conversion error (overflow) for row 4633809, column 82 (TF_ME_TOT_DEDUCTIONS).
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler,
TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean&
usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at CallSite.Target(Closure , CallSite , Object )
ClientConnectionId:ba9e07ac-1bc4-4c59-8a0a-167d7b281644
Error Number:4863,State:1,Class:16
Why is the rows affected count failing to return? Any ideas of how to get the count?
ExecuteNonQuery 不是 运行 查询的 "lowest level" 方法。它对 SQL 服务器可能 return 的信息做了一些简化假设。
当 运行 来自客户端的查询 SQL 服务器可以 return 错误消息、行计数消息和结果集的任意组合。但是为了简化正常情况,SqlClient 在看到错误消息时会抛出 SqlException,因此 ExecuteNonQuery 甚至 return(更不用说 return 行数了)。
如果您希望 ExecuteNonQuery return,您可以将所有错误消息重定向到事件处理程序,并使用 SqlConnection.FireInfoMessageEventOnUserErrors.
抑制 .NET 异常抛出行为