comment vérifier si une valeur null dans une seule ligne
J'obtiens une valeur de db, et lorsque la valeur est NULL j'obtiens une erreur
N'a pas pu convertir la variante de type (null) type (Entier)
Si je remplir dans la db avec 0 au lieu de rien (NULL) l'erreur disparaît
Donc, dis-je avoir cette
OneSpell.PerCent := FQuery.Recordset.Fields[ DB_FLD_PER_CENT ].Value;
OneSpell.Plus := TCardPlus ( FQuery.Recordset.Fields[ DB_FLD_PLUS ].Value );
OneSpell.Quantity := FQuery.Recordset.Fields[ DB_FLD_QUANTITY ].Value;
est-il un moyen de dire si la valeur est NULL puis le faire 0? Ou est-ce que avez à faire via la db.
FQuery
est un adoquery
et db est l'accès
Je sais que je pourrais faire
if .... = null then
onespell.plus := 0
else
.........
Mais je veux le faire en une seule ligne pour chaque valeur de onespell
Qu'est-ce que
eh bien, il était difficile d'expliquer ce qu'est exactement onespell est, mais le type de pour cent, et plus de la quantité doit être un entier. la base de données est énorme et va jeté, et en mettant tous 0 serait prendre un certain temps. et si ses null l'%, plus la quantité n'est pas utilisé donc j'ai pensé 0 à compresser l'erreur. J'ai été hopeing un moyen d'ajouter une instruction if dans une ligne quelque chose comme cela
Une fois de plus, qu'est-ce que
désolé je l'ai ajouté au dernier commentaire, mais le problème après l'avoir lu, mais oui FQuery est un TADOQuery, et oui, il y a plusieurs jeux d'enregistrements. comme dans le code, vous pouvez le faire plus rapidement avec une ? et de les garder tous dans la même ligne
Je n'ai aucune idée de comment vous pouvez l'éviter, parce que vous n'avez pas expliqué pourquoi votre requête a plusieurs jeux d'enregistrements dans la première place. La plupart des requêtes SQL ne pas retourner plus d'un, sauf si vous utilisez un
OneSpell
? De quel type sont PerCent
, Plus
, et Quantity
? Est FQuery
un TADOQuery
, ou quelque chose d'autre? Pouvez-vous être un peu plus spécifique, de sorte que nous pouvons essayer de vous aider? (Et oui, si vous voulez 0 au lieu de NULL, la solution la plus simple pour réduire le code est de le faire en SQL lui-même à l'aide de IsNull()
ou Coalesce()
ou quelque soit l'équivalent quelle que soit la non spécifié système de base de données que vous utilisez, car alors le code de votre application n'a pas besoin de s'inquiéter à propos de ce qui est retourné, il sait que ça sera une valeur numérique valide.)eh bien, il était difficile d'expliquer ce qu'est exactement onespell est, mais le type de pour cent, et plus de la quantité doit être un entier. la base de données est énorme et va jeté, et en mettant tous 0 serait prendre un certain temps. et si ses null l'%, plus la quantité n'est pas utilisé donc j'ai pensé 0 à compresser l'erreur. J'ai été hopeing un moyen d'ajouter une instruction if dans une ligne quelque chose comme cela
oneSpell.plus := if(null)then 0 else ....
mais pensé qu'il y avait une façon de le faire oui ses un adoquery , à l'aide de access db. mais plutôt de le faire dans ces lignes de code si possable...une fois une énorme db..Une fois de plus, qu'est-ce que
FQuery
? Est-il un TADOQuery
? (Il fait une différence, parce que ce qui est disponible pour une utilisation varie selon la classe. Aussi, si c'est un TADOQuery
, il y a vraiment plusieurs jeux d'enregistrements? Si pas, il n'y a pas besoin d'utiliser FQuery.RecordSet
, ce qui la rend plus facile.)désolé je l'ai ajouté au dernier commentaire, mais le problème après l'avoir lu, mais oui FQuery est un TADOQuery, et oui, il y a plusieurs jeux d'enregistrements. comme dans le code, vous pouvez le faire plus rapidement avec une ? et de les garder tous dans la même ligne
Je n'ai aucune idée de comment vous pouvez l'éviter, parce que vous n'avez pas expliqué pourquoi votre requête a plusieurs jeux d'enregistrements dans la première place. La plupart des requêtes SQL ne pas retourner plus d'un, sauf si vous utilisez un
TADOCommand
au lieu d'exécuter une série de SELECT
déclarations dans un script. (Je suis en supposant que vous êtes conscient que plusieurs jeux d'enregistrements ne sont pas les mêmes que plusieurs dossiers (lignes).)OriginalL'auteur Glen Morse | 2014-01-11
Vous devez vous connecter pour publier un commentaire.
Qui est la voie commune pour aller de l':
Extrait de la répétition de parties de garder le code SECS et pour augmenter la lisibilité
au
if value = NULL then
j'obtiens l'erreur que NULL n'est pas défini.NULL
est définie dans l'unitéVariants
OriginalL'auteur Sir Rufo
Parce que vous êtes à l'aide de la
ADOQuery.Recordset
, qui renvoie une référence à la sous-jacentes_Recordset
(ce qui n'est pas à partir de Delphi, mais est un objet ADO référence directement), vos choix sont limités à ceux qui ADO directement en charge. DelphiTADOQuery
a wrapper méthodes qui cachent beaucoup de la complexité de traiter avec ADO à un niveau inférieur, et à l'aide d'unRecordset
au lieu de cela limite considérablement vos options.AFAICT, la seule façon de le faire en une seule ligne serait à l'aide d'un long de la ligne de qui utilise à la fois le
VarIsNull
de la fonction et de laMath.IfThen
fonction (qui est par défaut0
si vous omettez leAFalse
paremeter):Vous pouvez le faire en deux lignes plus lisible avec un intermédiaire
OleVariant
variable (nécessitant laMath
unité):La méthode la plus simple solution de rechange (à partir d'un code Delphi point de vue, de toute façon) serait de les traiter dans votre requête SQL, en utilisant
IsNull
ouCoalesce
ou son équivalent dans MS Access, de sorte que vous n'avez pas à vous inquiéter à ce sujet dans le code de votre application; vous pouvez simplement accéder à l'Value
et de savoir qu'elle contient un entier à la place.En fait, la plus facile alternative est de ne pas utiliser
RecordSet
à tous si vous n'avez pas réellement besoin de le faire (parce qu'il y a plusieurs jeux d'enregistrements dans votreTADOCommand
résultats). Si vous utilisez simplement DelphiTADOQuery
directement, vous pouvez tout simplement utiliser le natifTField.AsXXX
propriétés, qui va gérer les conversions automatiquement pour vous:.AsInteger
serait plus facile. mais jusqu'à ce que je me souviens pourquoi j'ai utilisé le jeu d'enregistrements.. je vais aller la route à l'aide de mathématiques de l'unitéOriginalL'auteur Ken White
Arrêter de faire le travail dans le code delphi, votre requête doit gérer cela. La plupart DB backends l'appui de la FUSIONNER fonction. Donc, dans votre requête, il suffit d'utiliser :
SELECT COALESCE(MyIntegerField, 0) FROM Foo
. SiMyIntegerField
contient unNULL
valeur,COALESCE
sera de retour le premiernon-NULL
valeur, dans ce cas0
MODIFIER
Viens de réaliser que votre DB backend est MS Access, dans ce cas, utilisez la
IIF
fonction:OriginalL'auteur whosrdaddy
Si vous savez que vous voulez toujours la valeur Null interprété comme une Booléenne faux, 0 valeur numérique ou une chaîne vide, vous pouvez définir Système.Les variantes.NullStrictConvert = false.
(Strictement parlant, la valeur Null à la conversion de chaîne de la valeur de Système.Les variantes.NullAsStringValue seront prises).
OriginalL'auteur Jan Doggen
Voudrais essayer de montrer plus de deux variantes, qui vont hors de la boîte un peu.
1: utilisation de TDataSet accès natif
ou
en supposant que "DB_FLD_PLUS" a été une troisième colonne dans votre requête.
TField.AsInteger
renvoie zéro vide (NULL) colonnes.2: utilisation de Delphi avancée des dossiers
Puis ces trois lignes serait équivalent:
As<Type>
casting qui serait le mieux pourTCustomADODataSet
descendants depuis numériques typecasting retourne 0 si le champ sous-jacent estNULL
. Le problème est que l'OP n'est pas l'accès ADO jeu de données, mais le jeu d'enregistrements ADO, dont les champs sont deField
le type et les valeurs sont retournées commeOleVariant
.plz ne pas utiliser angulaire entre parenthèses: j'ai eu tant de minutes à essayer de comprendre où à utiliser des génériques ici 😀 Depuis le jeu de données est d'une enveloppe de plus de jeu, ce qui serait un problème lors de la lecture cette colonne particulière via TField?
Désolé pour ça 🙂 j'ai copié de mon supprimés réponse. Eh bien, cela dépend de l'usage réel de l'objet recordset d'accès utilisé ici. Il peut être dû à des raisons de performances, car il fournit la référence de l'objet recordset ADO interface), ou peut-être juste une erreur. Ou tout simplement une vitrine pour accéder aux prochains jeux de données (déclarés comme des variables) a été adjugé à travers les
NextRecordset
de la méthode. Dur à dire. Si c'est par erreur queAsType
casting serait à mon humble avis la façon la plus élégante (il serait d'ajouter un type de sécurité).OriginalL'auteur Arioch 'The