Spanner 在 GoogleSQL 和 PostgreSQL 資料庫中都支援 NUMERIC
資料類型。
GoogleSQL NUMERIC
GoogleSQL NUMERIC
是精確數值資料類型,可表示精確數值,有效位數為 38,小數位數為 9。本頁面概述用戶端程式庫中 NUMERIC
的表示方式。
PostgreSQL NUMERIC
PostgreSQL NUMERIC
類型是任意小數精確度的數值資料類型,最大精確度 (總位數) 為 147,455,最大比例 (小數點右側的位數) 為 16,383。
Spanner DDL 不支援為 PostgreSQL NUMERIC
欄指定有效位數和小數位數。不過,您可以在 DML 陳述式中將數值轉換為固定精確度值。例如:
update t1 set numeric_column = (numeric_column*0.8)::numeric(5,2);
型別 DECIMAL
是 NUMERIC
的別名。
指定主鍵、外鍵或次要索引時,無法使用 PostgreSQL NUMERIC
欄。
以各用戶端程式庫語言表示 NUMERIC
為維持 NUMERIC
值的準確度,每個 Spanner 用戶端程式庫都會以用戶端程式庫語言的適當資料類型儲存這些值。下表列出各支援語言中對應 NUMERIC
的資料類型。
語言 | GoogleSQL | PostgreSQL |
---|---|---|
C++ | spanner::Numeric | |
C# | SpannerNumeric | |
Go | big.Rat | Custom PGNumeric |
Java | BigDecimal | 自訂類型。請參閱 PostgreSQL Java 程式庫附註。 |
Node.js | Big | |
PHP | 自訂數值 | |
Python | 十進位 | 附帶自訂註解的十進位 |
Ruby | BigDecimal |
C++、C# 和 PHP 這三個用戶端程式庫各自實作了自訂型別,用來代表 Spanner SQL 的 NUMERIC
型別。其他所有程式庫都會使用現有型別。
C++ 用戶端程式庫 spanner::Numeric
物件不支援算術運算。請改為將所含數字轉換為所選的 C++ 物件。
舉例來說,您可以將數字擷取為字串,這樣就能以完整精確度呈現數字,不會遺失任何資料。不過,如果您事先知道該數字符合條件,例如在 std:int64_t
或 double
的範圍內,則可以將該值存取為該類型。
PostgreSQL Java 程式庫注意事項
Spanner Java 用戶端程式庫會使用自訂 Value.pgNumeric
型別儲存 PostgreSQL NUMERIC 值。
寫入 NUMERIC 資料欄
寫入 PostgreSQL 資料表的 NUMERIC 資料欄時,系統支援多種型別。
數值
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23)
整數
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1)
雙打
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23::float8)
未輸入型別的常值
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 'NaN')
參數化查詢
使用參數化查詢時,請以 $<index>
指定參數,其中 <index>
表示參數位置。然後使用 p<index>
繫結參數。例如,INSERT INTO MyTable (PgNumericColumn) VALUES ($1)
的參數為 p1
。
Java 用戶端程式庫支援下列類型做為參數化值:
自訂
Value.pgNumeric
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(Value.pgNumeric("1.23")) .bind("p2") .to(Value.pgNumeric("NaN")) .build()
雙打
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(1.23D) .bind("p2") .to(Double.NaN) .build()
整數
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1) .build()
長
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1L) .build()
異動
使用 Mutations 時,可將下列值寫入數值型別的資料欄:
字串
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to("1.23") .build()
BigDecimal 類型的值
BigDecimals
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(new BigDecimal("1.23")) .build()
Ints
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1) .build()
長
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1L) .build()
呼叫 Value.pgNumeric 後取得的值
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(Value.pgNumeric("1.23")) .build()
從 NUMERIC 資料欄擷取資料
如要取得 ResultSet 數字資料欄中儲存的值,請使用 ResultSet.getString()
或 ResultSet.getValue()
。
字串
resultSet.getString("PgNumericColumn")
自訂值
Value pgNumeric = resultSet.getValue("PgNumericColumn"); pgNumeric.getString(); // get underlying value as a String pgNumeric.getNumeric(); // get underlying value as a BigDecimal pgNumeric.getFloat64(); // get underlying value as aDouble
新增 NUMERIC 資料欄
以下範例顯示如何使用 Spanner 用戶端程式庫,將 NUMERIC
資料欄新增至名為 Venues
的資料表。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
更新 NUMERIC 資料
以下範例顯示如何使用 Spanner 用戶端程式庫更新 NUMERIC
資料。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
查詢 NUMERIC 資料
以下範例顯示如何使用 Spanner 用戶端程式庫查詢 NUMERIC
資料。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Spanner JDBC 驅動程式支援 NUMERIC
,使用 Java BigDecimal 型別。如需 NUMERIC
的使用範例,請參閱「透過 JDBC 連線至 GoogleSQL 方言資料庫」中的程式碼範例。
建立用戶端程式庫或驅動程式時處理 NUMERIC
NUMERIC
類型會編碼為 google.protobuf.Value Proto 中的十進位或科學記號字串。這個 proto 會包裝成 ResultSet、PartialResultSet 或 Mutation,視讀取或寫入作業而定。ResultSetMetadata 會使用 NUMERIC
TypeCode,指出對應值應讀取為 NUMERIC
。
在您建立的用戶端程式庫或驅動程式中使用 NUMERIC 時,請遵守下列指引。
如要從 ResultSet 讀取
NUMERIC
,請執行下列操作:當 TypeCode 為
NUMERIC
時,請從 google.protobuf.Value proto 讀取 string_value將該字串轉換為指定語言的相關型別
如要使用突變寫入
NUMERIC
,請在提供相關型別時,使用字串表示法做為 google.protobuf.Value Proto 中的 string_value。