Spanner admite el tipo de datos NUMERIC
en las bases de datos de GoogleSQL y PostgreSQL.
NUMÉRICO de GoogleSQL
El tipo de datos numérico exacto NUMERIC
de GoogleSQL puede representar un valor numérico exacto con una precisión de 38 y una escala de 9. En esta página se ofrece una descripción general de cómo se representa NUMERIC
en las bibliotecas de cliente.
NUMERIC de PostgreSQL
El tipo NUMERIC
de PostgreSQL es un tipo de datos numérico de precisión decimal arbitraria con una precisión máxima (total de dígitos) de 147.455 y una escala máxima (dígitos a la derecha del punto decimal) de 16.383.
DDL de Spanner no admite la especificación de precisión y escala para las columnas NUMERIC
de PostgreSQL. Sin embargo, los valores numéricos se pueden convertir en valores de precisión fija en las instrucciones DML. Por ejemplo:
update t1 set numeric_column = (numeric_column*0.8)::numeric(5,2);
El tipo DECIMAL
es un alias de NUMERIC
.
Las columnas de PostgreSQL NUMERIC
no se pueden usar al especificar claves principales, claves externas o índices secundarios.
Representar NUMERIC en cada lenguaje de biblioteca de cliente
Para mantener la fidelidad de los valores de NUMERIC
, cada biblioteca de cliente de Spanner almacena esos valores en un tipo de datos adecuado en el lenguaje de la biblioteca de cliente. En la siguiente tabla se indican los tipos de datos a los que se asigna NUMERIC
en cada idioma admitido.
Idioma | GoogleSQL | PostgreSQL |
---|---|---|
C++ | spanner::Numeric | |
C# | SpannerNumeric | |
Go | big.Rat | Custom PGNumeric |
Java | BigDecimal | Tipo personalizado. Consulta las notas de la biblioteca Java de PostgreSQL. |
Node.js | Big | |
PHP | Numérico personalizado | |
Python | Decimal | Decimal con anotación personalizada |
Ruby | BigDecimal |
Tres bibliotecas de cliente (C++, C# y PHP) han implementado un tipo personalizado para representar el tipo NUMERIC
de Spanner SQL. Todas las demás bibliotecas usan un tipo ya definido.
El objeto spanner::Numeric
de la biblioteca cliente de C++ no admite operaciones aritméticas. En su lugar, convierte el número incluido en el objeto de C++ que elijas.
Por ejemplo, puedes extraer el número como una cadena, que representaría el número con total fidelidad y sin pérdida de datos. Sin embargo, si sabes de antemano que ese número se encuentra, por ejemplo, en el intervalo de std:int64_t
o double
, puedes acceder al valor como ese tipo.
Notas de la biblioteca Java de PostgreSQL
La biblioteca de cliente de Java de Spanner usa un tipo Value.pgNumeric
personalizado
para almacenar valores NUMERIC de PostgreSQL.
Escribir en una columna NUMERIC
Se admiten varios tipos al escribir en una columna NUMERIC de una tabla PostgreSQL.
Caracteres numéricos
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23)
Números enteros
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1)
Dobles
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23::float8)
Literales sin tipo
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 'NaN')
Consultas con parámetros
Cuando uses consultas con parámetros, especifica los parámetros con $<index>
, donde <index>
indica la posición del parámetro. A continuación, el parámetro debe enlazarse mediante p<index>
. Por ejemplo, INSERT INTO MyTable (PgNumericColumn) VALUES ($1)
con el parámetro p1
.
La biblioteca de cliente de Java admite los siguientes tipos como valores parametrizados:
Personalizado
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()
Dobles
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(1.23D) .bind("p2") .to(Double.NaN) .build()
Números enteros
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1) .build()
Largos
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1L) .build()
Mutaciones
Cuando se usan mutaciones, se pueden escribir los siguientes valores en columnas de tipo numérico:
Cadenas
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to("1.23") .build()
Valores de tipos BigDecimal
BigDecimals
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(new BigDecimal("1.23")) .build()
Ints
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1) .build()
Largos
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1L) .build()
Valores obtenidos como resultado de una llamada a Value.pgNumeric
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(Value.pgNumeric("1.23")) .build()
Obtener datos de una columna NUMERIC
Para obtener los valores almacenados en las columnas numéricas de un objeto ResultSet, usa ResultSet.getString()
o ResultSet.getValue()
.
Cadenas
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
Añadir una columna NUMERIC
En el siguiente ejemplo se muestra cómo añadir una columna NUMERIC
a una tabla llamada Venues
mediante las bibliotecas de cliente de Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Actualizar datos NUMERIC
En el siguiente ejemplo se muestra cómo actualizar los datos de NUMERIC
mediante las bibliotecas de cliente de Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Consultar datos NUMERIC
En el siguiente ejemplo se muestra cómo consultar datos de NUMERIC
mediante las bibliotecas de cliente de Spanner.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
NUMERIC
se admite en el controlador JDBC de Spanner mediante el tipo BigDecimal de Java. Para ver ejemplos de cómo se usa NUMERIC
, consulta los ejemplos de código de Conectar JDBC a una base de datos con dialecto de GoogleSQL.
Gestionar NUMERIC al crear una biblioteca de cliente o un controlador
El tipo NUMERIC
se codifica como una cadena en notación decimal o científica dentro de un proto google.protobuf.Value. Este proto se encapsula como ResultSet, PartialResultSet o Mutation, según si se está leyendo o escribiendo. ResultSetMetadata usará NUMERIC
TypeCode para indicar que el valor correspondiente debe leerse como NUMERIC
.
Cuando trabajes con NUMERIC en una biblioteca o un controlador de cliente que crees, sigue estas directrices.
Para leer un
NUMERIC
de ResultSet, haz lo siguiente:Lee el valor de cadena del proto google.protobuf.Value cuando TypeCode es
NUMERIC
.Convierte esa cadena al tipo correspondiente del idioma en cuestión
Para escribir un
NUMERIC
mediante Mutations, usa la representación de cadena como string_value en el proto google.protobuf.Value cuando se le dé el tipo correspondiente.