加载包含 VARCHAR(MAX) 列的数据表时出错
我有 Powershell 以下函数,可以在给定连接字符串和查询的情况下通过 ODBC 从数据库加载数据。
function Run-OdbcSQL {
[OutputType([System.Data.DataTable])]
[cmdletbinding()]
param (
[Parameter(Mandatory)][string]$ConnString,
[Parameter(Mandatory)][string]$Query
)
$Conn = New-Object System.Data.Odbc.OdbcConnection
$Conn.ConnectionString = $ConnString
$Conn.Open()
try {
$Result =(New-Object Data.Odbc.OdbcCommand($Query,$Conn)).ExecuteReader()
$Table = New-Object "System.Data.DataTable"
$Table.Load($Result)
# Prevent PS from unravelling a table with a single row
Write-Output -NoEnumerate $Table
} finally {
$Conn.Close()
}
}
这工作正常,除非返回的列之一定义为 VARCHAR(MAX) 。在这种情况下,该函数返回错误:
Exception calling "Load" with "1" argument(s): "Failed to enable constraints.
One or more rows contain values violating non-null, unique, or foreign-key constraints."
如果我将查询修改为 SELECT CAST(column_name AS VARCHAR(255)) FROM …,则将毫无问题地加载数据。
环境:
- 数据库:SQL Server 2019
- ODBC 驱动程序:SQL Server Native Client 11.0 / ODBC Driver 18 for SQL Server(两者均可重现)
该问题似乎是 VARCHAR(MAX)
和 的组合System.Data.DataTable
,但我不知道如何解决它。
I have the Powershell following function to load data from a database via ODBC, given a connection string and a query.
function Run-OdbcSQL {
[OutputType([System.Data.DataTable])]
[cmdletbinding()]
param (
[Parameter(Mandatory)][string]$ConnString,
[Parameter(Mandatory)][string]$Query
)
$Conn = New-Object System.Data.Odbc.OdbcConnection
$Conn.ConnectionString = $ConnString
$Conn.Open()
try {
$Result =(New-Object Data.Odbc.OdbcCommand($Query,$Conn)).ExecuteReader()
$Table = New-Object "System.Data.DataTable"
$Table.Load($Result)
# Prevent PS from unravelling a table with a single row
Write-Output -NoEnumerate $Table
} finally {
$Conn.Close()
}
}
This works fine, except when one of the columns being returned, is defined as VARCHAR(MAX)
. In this case, the function returns the error:
Exception calling "Load" with "1" argument(s): "Failed to enable constraints.
One or more rows contain values violating non-null, unique, or foreign-key constraints."
If I modify the query to SELECT CAST(column_name AS VARCHAR(255)) FROM …
, the data will be loaded without any issue.
Environment:
- Database: SQL Server 2019
- ODBC driver: SQL Server Native Client 11.0 / ODBC Driver 18 for SQL Server (reproducible with both)
The issue seems to be a combination of VARCHAR(MAX)
and System.Data.DataTable
, but I can't figure how to resolve it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有明确的解决方案,但我设法找到了一些解决方法。
CAST(AS VARCHAR()
有效,但字符数限制为 8000 个,因为“SQL_CHAR
和SQL_VARCHAR
数据类型的最大长度限制为 8,000 个字符" [1][2]另一方面,
text
数据类型可以容纳 2^30 - 1 个字节(与NVARCHAR(MAX)
相同),看起来正确传递(无法找到任何具体信息),因此:`CAST( AS TEXT) 避免了该问题。查询 列定义为
VARCHAR(MAX)
,检索列内容长度为 100.000 个字符的单行。中间件:使用ODBC Driver 18 for SQL Server和SQL Server Native Client 11.0执行测试。两位车手的结果都是相同的。
数据库:Microsoft SQL Server 2019。
SELECT 查询
使用“1”个参数调用“Load”时发生异常:“无法启用约束。一个或更多行包含违反非空、唯一或外键约束的值。”
SELECT CAST(query as VARCHAR(8000))
SELECT CAST(query as VARCHAR(10000))
给类型“varchar”指定的大小 (10000) 超出了任何数据类型允许的最大值 (8000)。
SELECT CAST(query as TEXT)
备注
对于其他数据库(使用不同的中间件),此方法可能不起作用。例如,对于 PostgreSQL,您需要使用
MaxLongVarcharSize
属性,默认设置为8190
,最多支持65535
字节。No definite solution, but I have managed to find some workarounds.
The
CAST(<columnname> AS VARCHAR(<length>)
works, but you're limited to 8000 characters because "SQL_CHAR
andSQL_VARCHAR
data types are limited to a maximum length of 8,000 characters" [1][2]The
text
datatype on the other hand, can hold 2^30 - 1 bytes (identical toNVARCHAR(MAX)
) and it seems to be passed through correctly (couldn't find any concrete info). Thus: `CAST( AS TEXT) avoids the issue.Test case
Data: given a
query
column defined asVARCHAR(MAX)
, retrieving a single row where the contents of the column are 100.000 characters long.Middleware: Tests were executed using both ODBC Driver 18 for SQL Server and SQL Server Native Client 11.0. Results were identical for either driver.
Database: Microsoft SQL Server 2019.
SELECT query
Exception calling "Load" with "1" argument(s): "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."
SELECT CAST(query as VARCHAR(8000))
SELECT CAST(query as VARCHAR(10000))
The size (10000) given to the type 'varchar' exceeds the maximum allowed for any data type (8000).
SELECT CAST(query as TEXT)
Remarks
For other databases (using different middleware), this approach might not work. E.g. for PostgreSQL, you need to use the
MaxLongVarcharSize
property, which is set to8190
by default, and supports up to65535
bytes.