VARBINARY 列的 ODBC 数组提取导致服务器超时
ODBC array fetch of VARBINARY column causes server timeout
我有一个从 SQL 服务器数据库获取 VARBINARY(max)
数据的应用程序。在我的本地环境中,应用程序通过 SQL 驱动程序连接。 odbc_connect
的连接字符串包含:
DRIVER={SQL Server}
我正在像这样获取 VARBINARY 数据:
// Hexadecimal data of attachment
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_CONVERT);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$hex_data = $attach_row['attachment_value'];
$binary = hex2bin($hex_data);
效果很好。现在我需要在服务器上 运行 这个应用程序,我唯一的选择是将 ODBC 驱动程序 17 用于 SQL 服务器。连接字符串包含:
DRIVER={ODBC Driver 17 for SQL Server}
而且它不起作用。它在上面预览的第 6 行失败(odbc_fetch_array
)。我试过注释掉 odbc_binmode
和 odbc_longreadlen
行(我假设这个驱动程序可能会本地处理这些数据),但运气不佳,结果相同:服务不可用超时错误。
对于这个宽度的 ODBC 驱动程序 17 是否有不同的方法?
编辑: 我发现它挂在 ODBC_BINMODE_CONVERT
上。如果我将它更改为 ODBC_BINMODE_RETURN
,它会在几秒钟内变为 运行s - 但是输出是错误的。 ODBC_BINMODE_CONVERT
确实是我需要的,但是它没有及时处理全部数据(超时时间是30秒),这很奇怪,因为数据库中的VARBINARY字段只有65K字符长,而且它运行在我的本地环境中速度极快。
*Edit2: 我试图将从数据库中获取的不完整二进制数据转换为十六进制,然后转换为 PNG,它显示了一半的图像。所以我很肯定它正在获取正确的数据,获取该列的时间非常长,几乎在每种情况下都会导致超时。
好的。终于想通了最终对我有用的是使用 ODBC_BINMODE_RETURN
标志而不是 ODBC_BINMODE_CONVERT
,并且 NOT 最后使用 hex2bin()
转换。
我原来问题中的代码在 {SQL Server}
上运行良好,下面的代码在 {ODBC Driver 17 for SQL Server}
下运行:
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_RETURN);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$binary = $attach_row['attachment_value'];
我有一个从 SQL 服务器数据库获取 VARBINARY(max)
数据的应用程序。在我的本地环境中,应用程序通过 SQL 驱动程序连接。 odbc_connect
的连接字符串包含:
DRIVER={SQL Server}
我正在像这样获取 VARBINARY 数据:
// Hexadecimal data of attachment
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_CONVERT);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$hex_data = $attach_row['attachment_value'];
$binary = hex2bin($hex_data);
效果很好。现在我需要在服务器上 运行 这个应用程序,我唯一的选择是将 ODBC 驱动程序 17 用于 SQL 服务器。连接字符串包含:
DRIVER={ODBC Driver 17 for SQL Server}
而且它不起作用。它在上面预览的第 6 行失败(odbc_fetch_array
)。我试过注释掉 odbc_binmode
和 odbc_longreadlen
行(我假设这个驱动程序可能会本地处理这些数据),但运气不佳,结果相同:服务不可用超时错误。
对于这个宽度的 ODBC 驱动程序 17 是否有不同的方法?
编辑: 我发现它挂在 ODBC_BINMODE_CONVERT
上。如果我将它更改为 ODBC_BINMODE_RETURN
,它会在几秒钟内变为 运行s - 但是输出是错误的。 ODBC_BINMODE_CONVERT
确实是我需要的,但是它没有及时处理全部数据(超时时间是30秒),这很奇怪,因为数据库中的VARBINARY字段只有65K字符长,而且它运行在我的本地环境中速度极快。
*Edit2: 我试图将从数据库中获取的不完整二进制数据转换为十六进制,然后转换为 PNG,它显示了一半的图像。所以我很肯定它正在获取正确的数据,获取该列的时间非常长,几乎在每种情况下都会导致超时。
好的。终于想通了最终对我有用的是使用 ODBC_BINMODE_RETURN
标志而不是 ODBC_BINMODE_CONVERT
,并且 NOT 最后使用 hex2bin()
转换。
我原来问题中的代码在 {SQL Server}
上运行良好,下面的代码在 {ODBC Driver 17 for SQL Server}
下运行:
$query = 'SELECT * FROM attachments WHERE LOC_BLOB_ID = ' . $blob_id;
$attach_result = odbc_exec($connection, $query);
odbc_binmode($attach_result, ODBC_BINMODE_RETURN);
odbc_longreadlen ($attach_result, 262144);
$attach_row = odbc_fetch_array($attach_result);
$binary = $attach_row['attachment_value'];