將十進位字串及貨幣值格式化 (PDO_SQLSRV 驅動程式)

下載 PHP 驅動程式

為了保留精確度,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);
?>