Невозможно получить данные varbinary из MSSQL

Фон

Среда разработки:

PHP 7.0.3 с Apache 2.4.16 на Windows 10 x64

SQL Server 2014 Standard

На сервере включен FileStream для соответствующих файловых столбцов.

Пытался установить sqlsvr драйвер, но не удалось из-за отсутствия поддержки PHP7

Доступ к SQL-серверу из ODBC с помощью драйвера SQL Server

PHP-код для вставки данных изображения в MSSQL

$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();

PHP-код для сохранения данных изображения из MSSQL

$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. Открытие DATA каталог SQL Server, все загруженные файлы и могут быть открыты с помощью Paint.

Но выборка файла из вышеуказанного кода сохранения изображения повреждена. В файле отсутствуют некоторые байты из оригинала.

Метод попробовал

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

а также метод, указанный в этой ссылке.

Php с MSSQL отображать необработанные данные из поля varbinary

Но обоим не повезло, файл тоже казался поврежденным.

Любая помощь приветствуется.

Редактировать 2016-02-25

Изменил оператор SQL следующим образом, но выходной файл все еще поврежден.

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

Сейчас я пытаюсь изменить другой драйвер ODBC для SQL-сервера, чтобы посмотреть, может ли файл успешно выводиться.

Редактировать 2016-08-09

С обновленным MSSQL PDO Driver для PHP 7. Все снова заработало с очарованием.

Теперь нам не нужно convert varbinary данные больше, используя этот новый драйвер.

Ссылка Ссылка

5

Решение

При вставке в таблицы, содержащие varbinary, выбор типа данных очень важен для PHP PDO.

PDO::PARAM_LOB должен использоваться вместо использования PDO::PARAM_STR для файловых столбцов

Чтобы убедиться, что БД выдает правильный файл через драйвер, преобразуйте 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"]) );

Дополнительная информация

При выборе столбца varbinary из SQL Server Native Client 11.0 а также ODBC Driver 11 for SQL Serverне преобразовывая столбец в varchar или нет, PHP выводит поврежденный двоичный результат, который является нежелательным. Но водитель SQL Server успешно вернуть мне строку HEX при преобразовании столбца в VARCHAR(MAX), Я подозреваю, что это действие — ошибка или проблема с драйвером.

4

Другие решения

Если вы храните двоичные данные, не конвертируйте их в NVARCHAR () при выборе — попробуйте удалить CONVERT () из этого:

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

Вы также хотите убедиться, что ваш столбец VARBINARY(MAX),

При вставке данных я думаю, что вам нужно использовать SQLSRV_ENCODING_BINARY (вместо PDO::PARAM_STR)

3

  1. Установите сервер MSSQL
  2. Установите драйвер ODBC в соответствии с версией ОС и версией SQL Server.
    например, 64-разрядная версия Win 10 и SQL Server 12 требуется драйвер odbc 11

    Скачать по этой ссылке

  3. pdo_sqlsrv_.dll загрузка файлов в соответствии с версией php, вставка в каталог php / ext и открытие из раздела расширений php.ini. например,
    в моем случае установите версию xampp 3.2.2, включающую php 7.08, для
    это я скачать pdo_sqlsrv_7_ts.dll и установить в соответствии с вышеизложенным
    упомянуть в пункте 3.

    Скачать по этой ссылке:

  4. Установите параметр подключения к базе данных в PHP-файле, как

    $ conn = новый PDO («sqlsrv: server = 127.0.0.1,1433; база данных = test», «», «»);
    $ Conn-> SetAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);

-1
По вопросам рекламы [email protected]