Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-02-2016
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Comprobar si un valor es nulo

Me estoy volviedo loco. Estoy ejecutando este query en Builder 6 contra una base de datos Firebird:
Código SQL [-]
SELECT DISTINCT A.Situacion, B.Literal FROM Persona A LEFT JOIN Instalacion B ON A.Situacion = B.Valor AND B.Etiqueta = 'Situacion'
WHERE A.CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia') AND A.Sexo = 0 ORDER BY Situacion
que me devuelve este resultado:
Cita:
SITUACION LITERAL
-2 DESCONOCIDA
0 SITUACIÓN 1
1 SITUACIÓN 2
2 SITUACIÓN 3
3 SITUACIÓN 4
4 Null
Todo esto para cargar un TCheckListBox. Lo que pretendo es que me cargue un único ítem con el valor desconocida, de forma que no haya un ítem vacío. He probado de todo; ahora lo tengo puesto así:
Código:
for (; !fPersona->Query->Eof; fPersona->Query->Next())
{
     cAux = UpperCase(fPersona->Query->FieldByName("Literal")->AsString);
     if (lPrueba && (cAux == "DESCONOCIDA" || cAux == NULL))
     {
          CheckListBox2->Items->Add("Desconocida");
          lPrueba = true;
     }
     else if (cAux != NULL)
          CheckListBox2->Items->Add(fPersona->Query->FieldByName("Literal")->AsString);
}
pero también he probado con
Cita:
fPersona->Query->FieldByName("Literal")->IsNull
fPersona->Query->FieldByName("Literal")->AsString == ""
fPersona->Query->FieldByName("Literal")->AsString.IsEmpty()
Y siempre me añade al final un ítem con el caption vacío:
Responder Con Cita
  #2  
Antiguo 23-02-2016
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.068
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Puedes usar coalesce.
Código SQL [-]
SELECT DISTINCT A.Situacion, coalesce(B.Literal,'esto es nulo') FROM Persona ...
Responder Con Cita
  #3  
Antiguo 23-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Código PHP:
for (; !fPersona->Query->EoffPersona->Query->Next())
{
    if (
fPersona->Query->FieldByName("Literal")->IsNull)      
        Continue;
 
    
cAux UpperCase(fPersona->Query->FieldByName("Literal")->AsString);
    ...

AsString esta retornando un string vacio (''), no retorna NULL cuando el TField tiene valor Null
Responder Con Cita
  #4  
Antiguo 23-02-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.
Cita:
Empezado por Angel.Matilla Ver Mensaje
...
que me devuelve este resultado:
Código:
SITUACION  LITERAL
-2         DESCONOCIDA
 0 	   SITUACIÓN 1
 1 	   SITUACIÓN 2
 2         SITUACIÓN 3
 3         SITUACIÓN 4
 4         Null
¿ Y que resultado deseas obtener ?

Si deseas que cuando sea NULL figure DESCONOCIDA, podes hacer lo que te indicó Casimiro(es mejor) o tambíen:
Código PHP:
{
  
TIBQuery *qy static_cast<TIBQuery*>(fPersona->Query);

  for(
qy->First(); !qy->Eofqy->Next()) {
    
TField *fld qy->FieldByName("LITERAL");
    if (
fld->AsString == "DESCONOCIDA" || fld->IsNull)
      
CheckListBox1->Items->Add("Desconocida");
    else
      
CheckListBox1->Items->Add(fld->AsString);
  }
 ... 
que verifica la condición NULL del campo de forma similar a la respuesta de Agustín

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 23-02-2016 a las 14:34:12. Razón: corregir nombre de query
Responder Con Cita
  #5  
Antiguo 23-02-2016
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Puedes usar coalesce.
He usado tan pocas veces este comando que nunca me acuerdo de que existe. Es una buena idea.
Cita:
Empezado por AgustinOrtu Ver Mensaje
if (fPersona->Query->FieldByName("Literal")->IsNull)
Si te fijas es una de las cosas que he probado pero tampoco me funciona.
Cita:
Empezado por ecfisa Ver Mensaje
¿ Y que resultado deseas obtener ?
No, si el problema no es el resultado obtenido. De hecho cuento con él porque lo he provocado yo.
Cita:
Empezado por ecfisa Ver Mensaje
TField *fld = qy->FieldByName("LITERAL");
Este si funciona.

Muchas gracias a todos
Responder Con Cita
  #6  
Antiguo 23-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Como lo resolviste? IsNull funciona, ahora el caso es como se usa dentro de los condicionales claro
Responder Con Cita
  #7  
Antiguo 24-02-2016
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por AgustinOrtu Ver Mensaje
Como lo resolviste? IsNull funciona, ahora el caso es como se usa dentro de los condicionales claro
Así:
Código:
bool lPrueba = false;
for (; !fPersona->Query->Eof; fPersona->Query->Next())
     if (UpperCase(fPersona->Query->FieldByName("Literal")->AsString) != "DESCONOCIDA")
          CheckListBox2->Items->Add(fPersona->Query->FieldByName("Literal")->AsString);
     else if (!lPrueba)
     {
          CheckListBox2->Items->Add("Desconocida");
          lPrueba = true;
     }
Tuve que darle la vuelta al condicional porque si lo dejaba como estaba (con == en vez de !=) me seguía sacando dos veces ese literal, aunque todavía se puede mejorar ese código.

Lo de IsNull si que me ha extrañado que no funcionara porque de hecho le he usado con relativa frecuencia, tanto en BB.DD. Firebird como Paradox.
Responder Con Cita
  #8  
Antiguo 24-02-2016
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.917
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
No uso C++ (que afortunado!) pero ya que no te han explicado porque pasa esto, aqui va algo pa que no olvides, y que muchos lenguajes es lo mismo:
Cita:
Empezado por Angel.Matilla Ver Mensaje
cAux = UpperCase(fPersona->Query->FieldByName("Literal")->AsString);
if (lPrueba && (cAux == "DESCONOCIDA" || cAux == NULL))

https://stackoverflow.com/questions/...uit-evaluation

Por regla general, los AND y los OR utilizan "short circuit" y siguen la regla de las tablas de verdad. En este caso, si la 1era opcion en AND es verdadera, NO CHEQUEA LA SEGUNDA. Y lo mismo aplica en el OR

True And False = True
False OR True = True

El segundo problema es que UpperCase si te esta volviendo NULL? O cadena vacia?.
__________________
El malabarista.
Responder Con Cita
  #9  
Antiguo 24-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
En un AND donde encuentra el primer falso ya no chequea más
En un OR, con un sólo verdadero ya alcanza para que sea verdadero

Basicamente

(True) AND (True) AND (True) AND (True) AND (False) = False
(False) AND (True) AND (True) AND (True) AND (True) = False, solo se evalua el primer condicional

(True) OR (True) OR (True) OR (True) OR (False) = True, solo se evalua el primer condicional

Tiene cierto "truco", ya que a pesar de que aca estamos hablando de constantes True/False, muchas veces tenemos funciones que devuelven True o False. Y si bien es un error grave que tengan efectos colaterales, es para tener en cuenta, no se debe asumir que siempre se evaluan todas las condiciones; tambien es para tener en cuenta el orden en que encadenamos condiciones, lo propio es poner lo mas rapido primero y dejar lo pesado para el final

Se puede configurar el compilador para que haga Full Boolean Evaluation

Última edición por AgustinOrtu fecha: 24-02-2016 a las 16:47:15.
Responder Con Cita
  #10  
Antiguo 25-02-2016
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.309
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
No se si alguien lo ha comentado ya, pero ¿no puedes añadir la condición a la SQL, en lugar de tratarlo a posteriori?

Código SQL [-]
 ... AND (LITERAL IS NOT NULL)
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #11  
Antiguo 25-02-2016
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
... AND (LITERAL IS NOT NULL)
Esa condición no me vale. Fíjate que lo que me interesa es precisamente que salgan los valores nulos para saber que registros están mal grabados y la tabla en la que voy a buscar los literales no está indexada, ni me interesa, ya que es donde se guardan los valores básicos de configuración.

Última edición por Angel.Matilla fecha: 25-02-2016 a las 09:45:11.
Responder Con Cita
  #12  
Antiguo 25-02-2016
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

La situación no me termina de quedar clara... Cuando el valor de la columna LITERAL es NULL, ¿ Deseas que el ítem del CheckListBox incluya algún texto como sugiere la imágen de tu primer mensaje ?

Si no te interpreté mal y es así, creo que lo mas simple es hacerlo con la sugerencia de Casimiro, ejemplo :
Código PHP:
...
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  
TIBQuery *qy static_cast<TIBQuery*>(IBQuery1);

  
qy->Close();
  
qy->SQL->Clear();
  
qy->SQL->Add"SELECT DISTINCT A.SITUACION," );
  
qy->SQL->Add"COALESCE(UPPER(B.LITERAL), 'NULO') AS LITERAL" );
  
qy->SQL->Add"FROM PERSONA A LEFT JOIN INSTALACION" );
  
qy->SQL->Add"B ON A.SITUACION = B.VALOR ..." );
  ...
  for ( 
qy->Open(); !qy->Eofqy->Next() )
    
CheckListBox1->Items->Add(qy->FieldByName("LITERAL")->AsString );
  
CheckListBox1->Style lbOwnerDrawFixed;
}

void __fastcall TForm1::CheckListBox1DrawItem(TWinControl *Control,
      
int IndexTRect &RectTOwnerDrawState State)
{
  
TCheckListBox *lb static_cast<TCheckListBox*>(Control);
  
AnsiString str lb->Items->Strings[Index];

  if ( 
str == "NULO" ) {
    
lb->Canvas->Font->Color clRed;
    
lb->Canvas->Font->Style TFontStyles() << fsBold << fsUnderline;
  }
  
lb->Canvas->FillRectRect );
  
lb->Canvas->TextOutRect.leftRect.topstr );

Muestra:


Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #13  
Antiguo 25-02-2016
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por ecfisa Ver Mensaje
La situación no me termina de quedar clara... Cuando el valor de la columna LITERAL es NULL, ¿ Deseas que el ítem del CheckListBox incluya algún texto como sugiere la imágen de tu primer mensaje?
Perdón por explicarme tan mal. Lo que quiero es que cuando haya un valor NULL en la columna literal, al cargar el CheckListBox, se asocie a Desconocida. Más que nada, y lo sabéis, si un usuario del programa ve una casilla sin descripción como en el ejemplo que subí al principio o que la etiqueta ponga NULO como sugieres, tardan 30 segundos en llamarte para preguntarte que es eso de NULO. Lo he solucionado así:
Código:
Query->Close();
Query->SQL->Text = "SELECT DISTINCT A.Situacion, "
                   "COALESCE(B.Literal, 'Desconocida') Literal "
                   "FROM Persona A "
                   "LEFT JOIN Instalacion B "
                   "ON A.Situacion = B.Valor AND B.Etiqueta = 'Situacion' "
                   "WHERE A.CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')";
Query->Open();

bool lPrueba = false;
for (; !fPersona->Query->Eof; fPersona->Query->Next())
{
     if (UpperCase(fPersona->Query->FieldByName("Literal")->AsString) == "DESCONOCIDA")
     {
          if (lPrueba)
               continue;

          lPrueba = true;
     }
     CheckListBox2->Items->Add(fPersona->Query->FieldByName("Literal")->AsString);
}
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Comprobar si un campo es nulo Gabo C++ Builder 2 08-10-2007 23:08:11
Valor nulo en un string ElDioni Conexión con bases de datos 5 10-11-2005 09:29:57
Valor Nulo o en blanco y nil vtdeleon OOP 1 25-11-2004 05:41:50
Campo con valor nulo fjcg02 Conexión con bases de datos 4 10-11-2004 08:55:07
Valor nulo pache OOP 3 19-06-2003 08:39:13


La franja horaria es GMT +2. Ahora son las 10:12:21.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi