Perl DBI / FreeTDS / SQL-Server:如何插入/更新 BLOB varbinary(max) 数据?

Posted

技术标签:

【中文标题】Perl DBI / FreeTDS / SQL-Server:如何插入/更新 BLOB varbinary(max) 数据?【英文标题】:Perl DBI / FreeTDS / SQL-Server: How to insert/update BLOB varbinary(max) data? 【发布时间】:2021-01-31 03:05:53 【问题描述】:

我正在尝试通过 DBI 和 Linux 中的 freeTDS 将二进制数据插入 Microsoft SQL-Server 2014 上的 VARBINARY(max) 列。

以下(简化)代码不起作用:

$data = "foobar"; # real binary data gives same error
$dbh = <...valid db-handle ...>;
$sth = $dbh->prepare ("UPDATE table SET data=? WHERE id=?");
$sth->bind_param (1,$data,DBI::SQL_VARBINARY);
$sth->bind_param (2,$some_id);
$sth->execute or die ...

结果:

ct_result(ct_dynamic(CS_PREPARE)) returned -205 at /usr/lib/x86_64-linux-gnu/perl5/5.28/DBD/Sybase.pm line 138.
DBD::Sybase::db prepare failed: Server message number=257 severity=16 state=3 line=1 server=SERVER text=Implicit conversion from data type varchar to varbinary(max) is not allowed. Use the CONVERT function to run this query. Server message number=8180 severity=16 state=1 line=1 server=...
Can't call method "bind_param" on an undefined value 

似乎 bind_param 调用尾部正确编码二进制数据。未定义值错误似乎是绑定执行失败的结果。我为 bind_param 尝试了各种其他列类型,例如 SQL_LONGVARBINARY、SQL_BLOB ...但错误保持不变。

【问题讨论】:

【参考方案1】:

https://metacpan.org/pod/distribution/DBD-Sybase/dbd-sybase.pod#String-Data-Handling

DBD::Sybase 支持 CHAR/VARCHAR/BINARY/VARBINARY,直到 12.0x 版本的长度限制为 255 个字符。从 12.5 开始,这些数据类型的大小可以达到 16K - 但支持更大的大小需要使用 Open Client 12.5 或更高版本。

Sybase 不区分 CHAR 和 VARCHAR 或 BINARY 和 变量

似乎DBD::Sybase 忽略了DBI::SQL_VARBINARY 提示并将数据作为varchar 发送。

试试:

UPDATE table SET data=CONVERT(VARBINARY(max), ?, 1) WHERE id=?

还要检查syb_use_bin_0x 设置。

【讨论】:

这部分解决了问题。 DBD::Sysbase 似乎真的发送了VARCHAR。因此数据现在被截断为 1999 个字节:VARCHAR 的最大值为 4000,编码为带有前导 '0x' 的十六进制得到 1999 个字节。我尝试将其转换为VARCHAR(MAX),但这并没有改变任何东西。

以上是关于Perl DBI / FreeTDS / SQL-Server:如何插入/更新 BLOB varbinary(max) 数据?的主要内容,如果未能解决你的问题,请参考以下文章

Perl DBI - 使用多个语句运行 SQL 脚本

如何打印 Perl 的 DBI 填充占位符后执行的 SQL 查询?

Perl DBI - 加载到 SQL Server

使用 perl DBI 的 SQL 服务器事务问题

Perl 执行 DBI 循环执行

如何使用 Perl DBI 检索 DB2 SQL 存储过程的返回值?