首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 讀取 MSSQL ntext/nvarchar 欄位回傳空值完整解決方案

     編輯:PHP 相關知識

問題現象

使用 PHP mssql 擴展連接 SQL Server 時,ntext、nvarchar(max) 欄位查詢結果為空白,不報錯但無資料。

根本原因

  • mssql 擴展預設文字欄位長度限制 4096 位元組
  • ntext/nvarchar 使用 Unicode (UCS-2/UTF-16) 儲存,每字元 2-4 位元組,極易超過限制
  • 舊版 php_mssql.dll 基於 FreeTDS 0.91,對大型 Unicode 欄位支援不完善

方案一:修改 php.ini 設定 (最快)

; 尋找並修改 (移除前面分號)
mssql.textlimit = 2147483647
mssql.textsize = 2147483647

重啟 Apache/IIS 生效。這將文字欄位限制調至最大值 (2GB)。

方案二:SQL 查詢轉換型別 (推薦、無需改設定)

<?php
// ❌ 錯誤:直接查 ntext/nvarchar 會截斷或空值
// $sql = "SELECT title, content FROM article";

// ✅ 正確:轉換為非 Unicode 型別
$sql = "SELECT 
    CONVERT(VARCHAR(MAX), title) AS title,
    CONVERT(TEXT, content) AS content
FROM article";

$result = mssql_query($sql);
// 正常處理結果...
?>

型別對照表

原始型別轉換目標說明
nvarchar(n)VARCHAR(n)n ≤ 4000 時安全
nvarchar(max)VARCHAR(MAX)SQL Server 2005+
ntextTEXT相容舊版
nchar(n)CHAR(n)固定長度

方案三:使用 ADOdb 抽象層 (虛擬主機/無法改 php.ini)

<?php
include("adodb/adodb.inc.php");
$conn = NewADOConnection('odbc_mssql');
$conn->Connect("Driver={SQL Server};Server=localhost;Database=mydb;", 'username', 'password');

$rs = $conn->Execute("SELECT title, content FROM article");
while (!$rs->EOF) {
    echo $rs->fields['title'] . "
"; echo $rs->fields['content'] . "
"; $rs->MoveNext(); } ?>

ADOdb 內部處理了型別轉換,相容性較好。

方案四:升級至 sqlsrv / PDO_SQLSRV (根治、現代化)

💡 強烈建議:mssql 擴展 PHP 7.0+ 已完全移除。微軟官方維護 Microsoft Drivers for PHP for SQL Server (sqlsrv、PDO_SQLSRV),完整支援 ntext/nvarchar(max)、UTF-8、參數綁定、Always Encrypted 等新功能。

安裝步驟 (Windows)

  1. 下載 SQLSRV 驅動 (對應 PHP 版本、TS/NTS、x86/x64)
  2. 解壓縮 php_sqlsrv_74_nts_x64.dll、php_pdo_sqlsrv_74_nts_x64.dll 至 ext/
  3. php.ini 加入:
extension=php_sqlsrv_74_nts_x64.dll
extension=php_pdo_sqlsrv_74_nts_x64.dll

PDO_SQLSRV 範例

<?php
$serverName = "localhost";
$connectionInfo = ["Database" => "mydb", "UID" => "user", "PWD" => "pass", "CharacterSet" => "UTF-8"];
$pdo = new PDO("sqlsrv:Server=$serverName;Database=mydb", "user", "pass", [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

$stmt = $pdo->query("SELECT title, content FROM article");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['title'] . "
"; echo $row['content'] . "
"; } ?>

遷移檢查清單

  • [ ] 所有 mssql_connect → sqlsrv_connect / PDO
  • [ ] 所有 mssql_query → sqlsrv_query / PDO::query
  • [ ] 所有 mssql_fetch_array → sqlsrv_fetch_array / PDO::fetch
  • [ ] 移除 CONVERT(VARCHAR/TEXT, ...) 變通寫法
  • [ ] 確認連線字串 CharacterSet=UTF-8
  • [ ] 測試中文、Emoji、長文本正常讀寫

總結

短期可用 方案二 (SQL CONVERT) 快速修復;長期務必 遷移至 sqlsrv/PDO_SQLSRV,才是穩定、安全、支援現代 SQL Server 功能的正確道路。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved