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]

Responder a