為了保留精確度,decimal 或 numeric 類型一律會以字串形式擷取,並原樣保留其精度與小數位數。 如果任何值小於 1,則會遺漏前置零。 money 和 smallmoney 欄位也是如此,因為它們是小數位數固定為 4 的 decimal 類型欄位。
若遺漏前置零則加以新增
從 5.6.0 版開始,連線或陳述式屬性 PDO::SQLSRV_ATTR_FORMAT_DECIMALS 允許使用者對小數字串進行格式設定。 此屬性應為布林值(true 或 false),且只會影響擷取結果中的十進位值或數值格式。 換句話說,此屬性不影響插入或更新等其他作業。
根據預設,PDO::SQLSRV_ATTR_FORMAT_DECIMALS 是 false。 如果設定為 true,則會將十進位字串的前置零新增至小於 1 的任何十進位值。
設定小數位數的數目
當 PDO::SQLSRV_ATTR_FORMAT_DECIMALS 開啟時,另一個連接或陳述式屬性 (PDO::SQLSRV_ATTR_DECIMAL_PLACES) 可讓使用者設定顯示 money 和 smallmoney 資料時的小數位數數目。 其接受範圍在 [0, 4] 內的整數值,而在顯示時可能會發生進位。 不過,底層的金錢資料仍維持不變。
陳述屬性一律覆寫對應的連線設定。 請注意,PDO::SQLSRV_ATTR_DECIMAL_PLACES 選項只會影響金額資料,且 PDO::SQLSRV_ATTR_FORMAT_DECIMALS 必須設為 true。 否則,不論 PDO::SQLSRV_ATTR_DECIMAL_PLACES 設定為何,格式設定都會關閉。
注意
因為 money 或 smallmoney 欄位的小數位數為 4,所以如果將 PDO::SQLSRV_ATTR_DECIMAL_PLACES 設為負值或任何大於 4 的值,系統會忽略此設定。 不建議使用任何已格式化的金額資料作為任何計算的輸入資料。
設定連線屬性
在連線時設定屬性:
$attrs = array(PDO::SQLSRV_ATTR_FORMAT_DECIMALS => true, PDO::SQLSRV_ATTR_DECIMAL_PLACES => 2); $conn = new PDO("sqlsrv:Server = <server>; Database = <database>", $username, $password, $attrs);在建立連線後設定屬性:
$conn = new PDO("sqlsrv:Server = <server>; Database = <database>", $username, $password); $conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true); $conn->setAttribute(PDO::SQLSRV_ATTR_DECIMAL_PLACES, 2);
範例 - 格式化金額資料
以下範例說明如何使用 PDOStatement::bindColumn 取得 money 類型的資料:
<?php
$database = "<database>";
$server = "(local)";
$conn = new PDO( "sqlsrv:server=$server; Database = $database", "", "");
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
$numDigits = 3;
$query = "SELECT smallmoney1 FROM aTable";
$options = array(PDO::SQLSRV_ATTR_DECIMAL_PLACES => $numDigits);
$stmt = $conn->prepare($query, $options);
$stmt->execute();
$stmt->bindColumn('smallmoney1', $field);
$result = $stmt->fetch(PDO::FETCH_BOUND);
echo $field; // expect a number string with 3 decimal places
unset($stmt);
unset($conn);
?>
範例 - 覆寫連線屬性
以下範例說明如何覆寫連線屬性:
<?php
$database = '<database>';
$server = '<server>';
$username = '<user_id>';
$password = '<password>'
$conn = new PDO("sqlsrv:server=$server; Database = $database", $username, $password);
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
$conn->setAttribute(PDO::SQLSRV_ATTR_DECIMAL_PLACES, 2);
$query = 'SELECT smallmoney1 FROM testTable1';
$options = array(PDO::SQLSRV_ATTR_FORMAT_DECIMALS => false);
$stmt = $conn->prepare($query, $options);
$stmt->execute();
$stmt->bindColumn('smallmoney1', $field);
$result = $stmt->fetch(PDO::FETCH_BOUND);
echo $field; // expect a number string showing the original scale -- 4 decimal places
unset($stmt);
unset($conn);
?>