O Spanner é compatível com um tipo de dados NUMERIC nos bancos de dados do GoogleSQL e do PostgreSQL.
NUMERIC do GoogleSQL
O NUMERIC do GoogleSQL é um
tipo de dados numérico exato capaz de representar um valor numérico exato com uma
precisão de 38 e escala de 9. Esta página fornece uma visão geral de como NUMERIC
é representado nas bibliotecas de cliente.
NUMERIC do PostgreSQL
O tipo NUMERIC do PostgreSQL é um tipo de dados numérico de precisão decimal arbitrária
com uma precisão máxima (total de dígitos) de 147.455 e uma escala máxima
(dígitos à direita do marcador decimal) de 16.383.
A DDL do Spanner não permite especificar precisão e escala para colunas NUMERIC do PostgreSQL. No entanto, os valores numéricos podem ser convertidos em
valores de precisão fixa em instruções DML. Exemplo:
update t1 set numeric_column = (numeric_column*0.8)::numeric(5,2);
O tipo DECIMAL é um alias para NUMERIC.
As colunas NUMERIC do PostgreSQL não podem ser usadas ao especificar chaves primárias,
chaves externas ou índices secundários.
Representar NUMERIC em cada linguagem da biblioteca de cliente
Para manter a fidelidade dos valores NUMERIC, cada biblioteca de cliente do Spanner armazena esses valores em um tipo de dados apropriado na linguagem da biblioteca de cliente. A tabela a seguir lista os tipos de dados para os quais NUMERIC é mapeado em
cada idioma compatível.
| Idioma | GoogleSQL | PostgreSQL |
|---|---|---|
| C++ | spanner::Numeric | |
| C# | SpannerNumeric | |
| Go | big.Rat | PGNumeric personalizado |
| Java | BigDecimal | Tipo personalizado. Consulte Notas da biblioteca Java do PostgreSQL. |
| Node.js | Grande | |
| PHP | Numeric personalizado | |
| Python | Decimal | Decimal com anotação personalizada |
| Ruby | BigDecimal | |
| Rust | Decimal |
Três bibliotecas de cliente, C++, C# e PHP, implementaram um tipo personalizado para
representar o tipo NUMERIC do SQL do Spanner. Todas as outras bibliotecas usam um
tipo existente.
O objeto spanner::Numeric da biblioteca de cliente C++ não é compatível com operações
aritméticas. Em vez disso, converta o número contido no objeto C++ que você preferir.
Por exemplo, é possível extrair o número como uma string, que representa o
número na fidelidade total e sem perda de dados. No entanto, se você souber antecipadamente
que esse número se encaixa, por exemplo, no intervalo de std:int64_t ou double,
poderá acessar o valor como esse tipo.
Notas da biblioteca Java do PostgreSQL
A biblioteca de cliente Java do Spanner usa um tipo Value.pgNumeric personalizado
para armazenar valores NUMERIC do PostgreSQL.
Gravar em uma coluna NUMERIC
Vários tipos são aceitos ao gravar em uma coluna NUMERIC em uma tabela PostgreSQL.
Numéricos
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23)Números inteiros
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1)Duplas
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23::float8)Literais sem tipo
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 'NaN')
Consultas parametrizadas
Ao usar consultas parametrizadas, especifique os parâmetros com
$<index>, em que <index> denota a posição do parâmetro. O parâmetro precisa ser
vinculado usando p<index>. Por exemplo,
INSERT INTO MyTable (PgNumericColumn) VALUES ($1) com o parâmetro sendo
p1.
A biblioteca de cliente Java é compatível com os seguintes tipos como valores de parâmetro:
Personalizado
Value.pgNumericStatement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(Value.pgNumeric("1.23")) .bind("p2") .to(Value.pgNumeric("NaN")) .build()Duplas
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(1.23D) .bind("p2") .to(Double.NaN) .build()Números inteiros
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1) .build()Longs
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1L) .build()
Mutações
Ao usar mutações, os seguintes valores podem ser gravados em colunas de tipo numérico:
Strings
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to("1.23") .build()Valores dos tipos Big necessário
BigDecimals
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(new BigDecimal("1.23")) .build()Ints
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1) .build()Longs
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1L) .build()Valores obtidos como resultado de uma chamada para Value.pgNumérico
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(Value.pgNumeric("1.23")) .build()
Recuperar de uma coluna NUMERIC
Para conseguir valores armazenados em colunas numéricas de um ResultSet,
use ResultSet.getString() ou ResultSet.getValue().
Strings
resultSet.getString("PgNumericColumn")Valor personalizado
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
Adicionar uma coluna NUMERIC
O exemplo a seguir mostra como adicionar uma coluna NUMERIC a uma tabela chamada
Venues usando as bibliotecas de cliente do Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Atualizar dados NUMERIC
O exemplo a seguir mostra como atualizar dados NUMERIC usando as bibliotecas de cliente do Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Consultar dados NUMERIC
O exemplo a seguir mostra como consultar dados NUMERIC usando as bibliotecas de cliente do Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
O NUMERIC é compatível com o driver JDBC do Spanner usando o tipo BigDecimal do Java. Para exemplos de como o
NUMERIC é usado, consulte os exemplos de código em
Conectar o JDBC a um banco de dados de dialeto do GoogleSQL.
Processar NUMERIC ao criar uma biblioteca de cliente ou um driver
O tipo NUMERIC é codificado como uma string em notação decimal ou científica
dentro de um proto google.protobuf.Value. Esse proto é encapsulado como
ResultSet, PartalResultSet ou Mutação, dependendo se
ele está sendo lido ou gravado. ResultSetMetadata usará o TypeCode
NUMERIC para indicar que o valor correspondente precisa ser lido como
NUMERIC.
Ao trabalhar com NUMERIC em uma biblioteca de cliente ou um driver que você criar, observe a orientação a seguir.
Para ler um
NUMERICno ResultSet:Ler o string_value do proto google.protobuf.Value quando TypeCode for
NUMERICConverta essa string no tipo relevante para o dado idioma
Para gravar um
NUMERICusando mutações, use a representação de string como o string_value no proto google.protobuf.Value quando solicitado.