Le bug qui stocke Unicode dans Delphi7?
Récemment, lors de l'utilisation de Delphi7 pour effectuer des programmes Unicode, j'ai découvert un tel problème, c'est-à-dire que lorsque vous utilisez le composant TadoCommand pour exécuter des instructions SQL, s'il y a des caractères Unicode dans l'instruction SQL, le code brouillé apparaîtra dans la base de données, et il en va de même Céroviaire pour l'utilisation de TTNTADOQUERY (l'utilisation des paramètres n'est pas qu'il y aura du code brouillé, et ici nous ne discuterons que de la méthode SQL pure). Cependant, TadoCommand prend en charge le plus large et la propriété CommandText est également de type plus large. J'ai essayé de modifier plusieurs valeurs d'attribut de Tadocommand et j'ai trouvé un phénomène étrange. Pourquoi cela se produit-il? Cette propriété semble n'avoir rien à voir avec Unicode lui-même. En étudiant le fichier adodb.pas où se trouve Tadocommand, j'ai trouvé le problème.
Procédure tadoCommand.AssignCommandText (Valeur const: largestring; chargement: booléen);
procédure initparameters;
var
I: entier;
Liste: TParameters;
NativeCommand: String;
Commencer
Liste: = tParameters.Create (self, tParameter);
essayer
NativeCommand: = list.parsesql (valeur, true);
{Préserver les valeurs existantes}
List.assignValues (paramètres);
CommandObject.CommandText: = NativeCommand;
en cas de chargement et (attribué (connexion) ou (connectionString <> '')) puis
Commencer
essayer
SetConnectionFlag (cfParameters, true);
essayer
{Récupérer des informations de paramètres supplémentaires du serveur si pris en charge}
Paramètres.InternalRefresh;
{Utilisez des informations de paramètres supplémentaires à partir du serveur pour initialiser notre liste}
si paramètres.count = list.count alors
pour i: = 0 à list.Count - 1 do
Commencer
List [i] .datatype: = paramètres [i] .datatype;
List [i] .size: = paramètres [i] .size;
List [i] .numericscale: = paramètres [i] .numericsCale;
List [i] .précision: = paramètres [i] .précision;
List [i] .direction: = Paramètres [i] .direction;
List [i] .attributes: = paramètres [i] .attributes;
fin
Enfin
SetConnectionFlag (cfParameters, false);
fin;
sauf
{Ignorer l'erreur si le serveur ne peut pas fournir des informations de paramètre}
fin;
si list.Count> 0 alors
Paramètres.Assign (list);
fin;
Enfin
List.free;
fin;
fin;
Commencer
if (commandType = cmdText) et (valeur <> '') et paramcheck alors
Initparameters
autre
Commencer
CommandObject.CommandText: = Value;
Si ce n'est pas le chargement, Paramètres.Clear;
fin;
fin;
Jetez un œil à cette déclaration:
if (commandType = cmdText) et (valeur <> '') et paramcheck alors
Initparameters
Autrement dit, lorsque ParamCheck est vrai, le processus initParameters sera exécuté.
Tout d'abord, il définit une variable: NativeCommand: String;
NativeCommand: = list.parsesql (valeur, true);
{Préserver les valeurs existantes}
List.assignValues (paramètres);
CommandObject.CommandText: = NativeCommand;
Ici, la valeur est de type plus large, et List.PaSesQL renvoie le type de chaîne, et NativeCommand est également de type de chaîne. ce qui fait que commandObject.commandText n'obtient pas la valeur plus large qui doit lui être attribuée, ce qui conduit finalement à la survenue d'un code brouillé lors du stockage Unicode.
La solution est également très simple (si vous n'êtes pas disposé à modifier le programme source Delphi), vous avez juste besoin de définir ParamCheck sur FALSE (Delphi par défaut est paramcheck vers true).