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 | 自訂 PGNumeric |
| Java | BigDecimal | 自訂類型。請參閱 PostgreSQL Java 程式庫附註。 |
| Node.js | Big | |
| PHP | 自訂數值 | |
| Python | Decimal | 十進位,含自訂註解 |
| 小茹 | BigDecimal | |
| Rust | Decimal |
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.pgNumericStatement .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
小茹
更新 NUMERIC 資料
以下範例說明如何使用 Spanner 用戶端程式庫更新 NUMERIC 資料。
C++
C#
Go
Java
Node.js
PHP
Python
小茹
查詢 NUMERIC 資料
以下範例說明如何使用 Spanner 用戶端程式庫查詢 NUMERIC 資料。
C++
C#
Go
Java
Node.js
PHP
Python
小茹
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。