Hola Pedro, hola gente,
Pedro escribió:
Hola Ariel,
Retomando el tema pendiente en mi base de datos, referente a INSERT
INTO. Estoy usando la configuración local como separador decimal, es
decir la coma " , ", efectivamente SQL únicamente permite usar el
punto. Ahora, mi problema es que necesito ingresar esta variable a la
nueva tabla, esta variable está declarada como Object en el formulario.
¿por qué la declaras como Object? ¿la obtienes de algún control del
formulario, p.e. miVar = oMiForm.getByName("control_xxx")?
INSERT INTO Sólo me permite almacenar la variable como texto al
convertirla con CStr, respetando los decimales, pero una vez en la
tabla, no puedo realizar operación matemática con ese campo. Entonces,
las preguntas son:
1.- ¿Cómo puedo almacenar la variable como número en la tabla sin tener
que cambiar la configuración del sistema?
Mira si los ejemplos en
http://www.arielconstenlahaile.com.ar/ooo/temp/INSERT_INTO.odb
responden tu pregunta.
Es posible teniendo en cuenta todos los aspectos involucrados:
1. cómo obtienes el dato que deseas guardar [ver NOTA 1]
2. en qué tipo de variable lo almacenas
3. en qué tipo de campo lo deseas guardar
4. qué instrucción SQL empleas para insertar los datos en la tabla
Supongamos que estamos trabajando con la siguiente tabla HSQLDB:
CREATE CACHED TABLE "TEST_DECIMAL_SEP"(
"id" INTEGER
GENERATED BY DEFAULT AS IDENTITY
(START WITH 0)
NOT NULL
PRIMARY KEY,
"field1" DECIMAL(15,5),
"field2" DECIMAL(15,5),
"field3" DECIMAL(15,5),
"field4" DECIMAL(15,5)
);
La instrucción SQL que deseamos ejecutar empleando OOo Basic es:
sSQL = "INSERT INTO ""TEST_DECIMAL_SEP"" VALUES (" &_
"NULL ," &_
"1234567890.12345," &_
"CAST( '43210.123' AS DECIMAL )," &_
CDbl("6543,0123") & "," &_
CDbl("6543.0123") & ")"
todas esas expresiones se transforman automáticamente, por el simple
hecho de concatenarlas mediante el operador &, en la siguiente cadena:
"INSERT INTO "TEST_DECIMAL_SEP" VALUES (NULL ,1234567890.12345,CAST(
'43210.123' AS DECIMAL ),6543,0123,65430123)"
Al ejecutar esta instrucción SQL, genera el siguiente error:
"Se ha producido una excepción
Type: com.sun.star.sdbc.SQLExceptionMessage:
*Column* *count* does *not* match in statement [INSERT INTO
"TEST_DECIMAL_SEP"
VALUES (NULL ,1234567890.12345,CAST( '43210.123' AS DECIMAL ),6543,0123,]."
La causa de ese error:
CDbl("6543,0123") convierte la cadena "6543,0123" en un valor tipo
Double, PERO al concatenar el valor de retorno en la cadena sSQL estamos
implícitamente transformándolo a cadena, siendo equivalente a
CStr(CDbl("6543,0123") ), lo cual, en CASTELLANO, retorna una cadena con
una coma en el separador decimal: "6543,0123".
Al ejecutar la instrucción SQL, en "6543,0123" la coma NO es
interpretada como separador decimal, sino como indicando que se trata de
DOS VALORES DISTINTOS: 6543 y 0123; por lo tanto hay una columna de más
en la instrucción INSERT.
El problema es que estamos transformando una cadena a un Double
(CDbl("6543,0123") ), pero luego al concatenar este valor Double en la
cadena sSQL lo volvemos a transformar en una cadena, transformación
dependiente de la config. *regional* del sistema.
La solución NO es transformar en Double una cadena con punto como
separador decimal, porque en la config. de idioma castellano
CDbl("6543.0123") se convierte en un entero 65430123.
Solución:
1. Eliminar el indicador de MILES
2. Reemplazar la COMA del separador decimal por el PUNTO.
Function formatNumber(aNumber) as String
On Error Resume Next
Dim aTemp, sReturn
'si el valor se obtiene como una cadena
'de un campo formateado tipo 1.234,56
'quitar primero el indicador de MILES
aTemp = CDbl(aNumber)
'cambiar el separador decimal
sReturn = Join( Split(aTemp,","), ".")
formatNumber() = sReturn
End Function
Esta solución sigue siendo dependiente de la configuración local: si la
config. local es castellano y se intenta pasar un número con formato
inglés como
1,234,567.012
CDbl(aNumber) generaría un error, como lo explica la Ayuda para esa
función de OpenOffice.org Basic:
"Para convertir una expresión de cadena, el número debe introducirse
como texto normal ("123,5") usando el formato numérico predeterminado
del sistema operativo."
2.- Si es almacenada como texto en la tabla, ¿hay alguna forma de
convertirla a número en una consulta?
se puede emplear la función de HSQLDB *CAST*
Es posible insertar un literal tipo cadena y convertirlo a DECIMAL mediante
CAST(<some_value> AS <TARGET_TYPE>)
por ejemplo:
INSERT
INTO "TEST_DECIMAL_SEP"
VALUES (
NULL,
CAST('1234567890.12345' AS DECIMAL),
NULL,
NULL,
NULL
);
Ten en cuenta que en este caso el CAST funcionará si el tipo al cual
deseas convertir es DOUBLE, DECIMAL, NUMERICAL... PERO no INTEGER,
SMALINTEGER etc... porque el valor tiene separador decimal:
'1234567890.12345'. Pero CAST('1234567890' AS INTEGER) *sí* funciona,
por más que el tipo del campo en el cual lo deseas insertar es DECIMAL.
Obviamente, el separador decimal en la cadena de esta función HSQLDB es
el *PUNTO*, *no* la COMA. Así que no sales del problema anterior.
Creo que la solución es mantener la configuración regional, y emplear
alguna función como la que indiqué arriba para reemplazar la COMA por el
PUNTO como separador decimal.
Emplea variables tipo Double, manipula mediante operaciones matemáticas
necesarias, y POR ÚLTIMO la conviertes a cadena y reemplazas la como por
el punto.
Espero que te sea de ayuda; en cualquier caso, no dudes en consultar y
cuenta cómo te ha ido.
Saludos
Ariel
***********************************************************************
NOTA 1:
Si obtienes los datos del control de un formulario, dependerá del tipo
de control, y si los obtienes empleando los métodos del control o alguna
propiedad del modelo. Para citar sólo dos ejemplos, el "campo
formateado" y el "campo numérico":
* UnoControlFormattedField/UnoControlFormattedFieldModel
** UnoControlFormattedField
XTextComponent::getText() retorna una cadena
** UnoControlFormattedFieldModel
UnoControlFormattedFieldModel::EffectiveValue retorna double
UnoControlFormattedFieldModel::Text retorna una cadena
* UnoControlNumericField/UnoControlNumericFieldModel
** UnoControlNumericField
XTextComponent::getText() retorna una cadena
XNumericField::getValue() retorna double
** UnoControlNumericFieldModel
UnoControlNumericFieldModel::Value retorna double
--
Ariel Constenla-Haile
La Plata, Argentina
[EMAIL PROTECTED]
[EMAIL PROTECTED]
http://www.arielconstenlahaile.com.ar/ooo/
"Aus der Kriegsschule des Lebens
- Was mich nicht umbringt,
macht mich härter."
Nietzsche Götzendämmerung, Sprüche und Pfeile, 8.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]