gpt4 book ai didi

sql - "String data, right truncation"通过 ODBC 但不是通过具有相同查询的 SQL Server 管理器

转载 作者:太空狗 更新时间:2023-10-29 11:22:18 24 4
gpt4 key购买 nike

我在一台服务器上有一个 LAPP 堆栈,在另一台服务器上运行 MSSQL。前者通过微软的 ODBC Driver 1.0 for Linux 连接到后者并且通常效果很好。

如果查询字符串太长,我们的一个搜索页面将失败并出现以下错误:

Couldn't execute statement: [unixODBC][Microsoft][SQL Server Native Client 11.0]String data, right truncation (SQL-22001)

但是,如果我复制查询,将其粘贴到连接到同一数据库的 MS SQL Server Manager 查询窗口中,将所有 ? 占位符替换为我的脚本传递给 $ 的内容sth->execute(),并运行它,它不会产生错误。

这是为什么? (这是否表示 ODBC 驱动程序或 SSM 中存在错误,或者只是两者之间存在差异?)

更好的是,或者我想我的最终目标是:如何让我的脚本像 SSM 那样运行?目前我能看到的唯一解决方法是遍历每一列(有很多列,它是 5 个查询的联合,每个查询都有很多表连接)并找出查询字符串可能的每个 varchar 列的长度every be too long for,然后按长度区分所有的占位符。 IE。我必须自己进行截断并且还有另一个代码依赖性——例如,当我们的数据库供应商决定延长列时,我必须去减少列出现的任何脚本中的截断。ODBC 不能驱动程序像 SSM 一样“正常工作”,没有提示?

如果我启用跟踪,我会为每个占位符获取其中之一:

-dbd_bind_ph=rebind_param
+rebind_param 7 '%aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%' (size svCUR=43/SvLEN=48/max=0) svtype:8, value type:1, sql type:0
+get_param_type(7f22ca950e88,7)
bind 7 '%aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...' value_len=43 maxlen=47 null=0)
bind 7 value_type:1 VARCHAR cs=20 dd=0 bl=43
-rebind_param
+dbd_bind_ph(7f22ca950e88, name=8, value='%aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa%', attribs=, sql_type=0(unknown), is_inout=0, maxlen=0
First bind of this placeholder

似乎 cs=... 是变化的并且似乎对应于我在该上下文中可以摆脱的最大占位符大小。有没有一种方法可以访问该 cs 值,以便我可以在绑定(bind)它之前限制该值,但要动态地进行限制,这样我就没有这些额外的代码依赖性?也许这就是 SSM 自动执行的操作?

更新:我在 DBD::ODBC::FAQ under "Why am I getting errors with bound parameters?" 中找到了在“数据截断错误”下或多或少地描述了这个问题。我真的必须遍历每个参数以将其固定为 SQLDescribeParam 返回的长度(减去 2,因此我可以在开始和结束处添加“%”符号进行搜索) ...但是如果我使用任何类型的连接,那甚至不能保证工作,因为它可能会弄错长度?这张照片有什么问题吗?

更新 2: 我刚找到 here那,“如果您正在使用适用于 Linux 的 Microsoft SQL Server ODBC 驱动程序 1.0,则应升级到适用于 SQL Server 的 Microsoft ODBC 驱动程序 11。”关闭尝试...UPDATE2.5 在最新的 libmsodbcsql-11.0.so.2270.0 驱动程序上,它也表现出这种行为。

最佳答案

多亏了 bohica,DBD::ODBC 现在导出了一个函数 odbc_describe_param,它公开了 super 文本搜索情况的解决方法的必要信息:

# $sth is an already-prepared statement
for (1..(scalar keys %{$sth->{ParamTypes}})) {
my @help = $sth->odbc_describe_param($_);
if ($help[1]) { # like SQLDescribeParam API - i.e., type, size, decimal digital and nullable
$sth->bind_param($_, '%' . substr($s, 0, $help[1] - 2) . '%');
} else { # 0 = false = unlimited length allowed
$sth->bind_param($_, '%' . $s . '%');
}
}
$sth->execute();
...

关于sql - "String data, right truncation"通过 ODBC 但不是通过具有相同查询的 SQL Server 管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21605992/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com