gpt4 book ai didi

php - 无法从 MSSQL 获取 varbinary 数据

转载 作者:可可西里 更新时间:2023-11-01 14:01:00 26 4
gpt4 key购买 nike

背景

开发环境:

Windows 10 x64 上的 PHP 7.0.3 和 Apache 2.4.16

SQL Server 2014 标准版

服务器在相应的文件列上启用了 FileStream。

尝试安装 sqlsvr 驱动程序,但由于不支持 PHP7 而失败

使用驱动程序 SQL Server 从 ODBC 访问 SQL 服务器

将图像数据插入 MSSQL 的 PHP 代码

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);
$stmt = $link->prepare("INSERT INTO [Attachment] (AttID, Seq , ModuleCde, AppID, StaffID , FileName , [File]) VALUES ( NEWID() , ? , ? , ? , ? , ? , ? )");
$stmt->bindValue(1,$_POST["Seq"],PDO::PARAM_INT);
$stmt->bindValue(2,$_POST["ModuleCde"],PDO::PARAM_STR);
$stmt->bindValue(3,$_POST["AppID"],PDO::PARAM_STR);
$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);
$stmt->bindValue(5,$_FILES["file"]["name"][$_POST["Seq"]],PDO::PARAM_STR);
$stmt->bindValue(6,file_get_contents($_FILES["file"]["tmp_name"][$_POST["Seq"]]),PDO::PARAM_STR);
$stmt->execute();

从 MSSQL 保存图像数据的 PHP 代码

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);
$stmt = $link->prepare("SELECT DATALENGTH([File]) AS [Size] , CONVERT(NVARCHAR(MAX),[File],2) AS [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");
$stmt->bindValue(1,$_GET["ModuleCde"],PDO::PARAM_STR);
$stmt->bindValue(2,$_GET["AppID"],PDO::PARAM_STR);
$stmt->bindValue(3,$_GET["Seq"],PDO::PARAM_STR);
$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);
$stmt->execute();
$stmt->bindColumn(2,$img,PDO::PARAM_LOB, 0);
$stmt->fetch(PDO::FETCH_ASSOC);
file_put_contents( "file" , $img );

文件成功上传到SQL服务器。打开SQL Server的DATA目录,所有上传的文件都可以用画图打开。

但是从上面的图像保存代码中获取的文件已损坏。该文件缺少原始文件中的一些字节。

尝试过的方法

fwrite( fopen("file","w+") , strtolower("0x".str_replace("\0","",$img)) );

以及此链接中所述的方法。

Php with MSSQL display raw data from varbinary field

但都没有运气,文件似乎也已损坏。

感谢任何帮助。

编辑 2016-02-25

修改SQL语句如下,但输出文件仍然损坏。

 $link->prepare("SELECT DATALENGTH([File]) AS [Size] , [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");

我现在正在尝试更换不同的SQL Server ODBC驱动,看看文件能否输出成功。

编辑 2016-08-09

使用更新后的适用于 PHP 7 的 MSSQL PDO 驱动程序。一切都恢复正常了。

现在,我们不再需要使用这个新驱动程序转换 varbinary 数据。

Reference Link

最佳答案

当插入到包含 varbinary 的表时,数据类型的选择对 PHP PDO 非常重要。

PDO::PARAM_LOB 应使用 PDO::PARAM_STR 用于文件列

为确保 DB 通过驱动程序输出正确的文件,将 VARBINARY(MAX) 字段转换为十六进制字符串,并使用此方法将其正常交给 PHP CONVERT(VARCHAR( MAX),[FileColumn],2)

将列转换为 VARCHAR(MAX) 而不是 NVARCHAR(MAX) 因为 HEX 字符串不需要对 Unicode 的任何支持并留下一个普通的 HEX 字符串。

然后可以通过 PHP 函数 hex2bin() 高效地将十六进制字符串从十六进制数据转换回二进制。

解决方案

$link = @new \PDO("odbc:Driver={SQL Server};Server=$server;Database=$db", $user, $password);
$stmt = $link->prepare("SELECT DATALENGTH([File]) AS [Size] , CONVERT(VARCHAR(MAX),[File],2) AS [File] FROM [Attachment] WHERE [ModuleCde] = ? AND [AppID] = ? AND [Seq] = ? AND [StaffID] = ?");
$stmt->bindValue(1,$_GET["ModuleCde"],PDO::PARAM_STR);
$stmt->bindValue(2,$_GET["AppID"],PDO::PARAM_STR);
$stmt->bindValue(3,$_GET["Seq"],PDO::PARAM_STR);
$stmt->bindValue(4,$_SESSION["StaffID"],PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
file_put_contents( "file" , hex2bin($result["File"]) );

附加信息

当从 SQL Server Native Client 11.0ODBC Driver 11 for SQL Server 中选择 varbinary 列时,既没有将该列转换为 varchar 也没有, PHP 输出损坏的二进制结果,这是不需要的。但是当我将列转换为 VARCHAR(MAX) 时,驱动程序 SQL Server 成功地向我返回了一个 HEX 字符串。我怀疑此操作是错误或驱动程序问题。

关于php - 无法从 MSSQL 获取 varbinary 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35596259/

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