O bug que armazena Unicode em Delphi7?
Recentemente, ao usar o Delphi7 para fazer programas Unicode, descobri esse problema, ou seja, ao usar o componente tadocommand para executar instruções SQL, se houver caracteres unicode na instrução SQL, o código contínuo aparecerá no banco de dados e o mesmo for Verdadeiro para o uso de ttntadoQuery (o uso de parâmetros não é que haverá código ilegal e aqui discutiremos apenas o método puro SQL). No entanto, o próprio Tadocommand suporta WideString, e a propriedade CommandText também é do tipo WideString. Tentei alterar vários valores de atributo de Tadocommand e encontrei um fenômeno estranho. Por que isso acontece? Esta propriedade parece não ter nada a ver com o próprio Unicode. Ao estudar o arquivo adodb.pas onde o Tadocommand está localizado, encontrei o problema.
Procedimento tadocommand.assignCommandText (Valor const: wideString; carregamento: booleano);
procedimento initParameters;
var
I: Inteiro;
Lista: tparameters;
NativeCommand: string;
Começar
Lista: = tparameters.create (self, tparameter);
tentar
NativeCommand: = list.parsesql (valor, true);
{Preserve os valores existentes}
List.assignValues (parâmetros);
CommandObject.CommandText: = nativEcommand;
se não estiver carregando e (atribuído (conexão) ou (conextionString <> '')) então
Começar
tentar
SetConnectionFlag (CFParameters, True);
tentar
{Recupere as informações adicionais do parâmetro do servidor, se suportadas}
Parâmetros.internalRefresh;
{Use informações adicionais do parâmetro do servidor para inicializar nossa lista}
Se parâmetros.count = list.count então
para i: = 0 para listar.count - 1 do
Começar
Lista [i] .datatype: = parâmetros [i] .datatype;
Lista [i] .Size: = parâmetros [i] .size;
Lista [i] .NumericScale: = Parâmetros [i] .NumericsCale;
List [i] .Precision: = Parâmetros [i] .Precision;
Lista [i] .Direction: = Parâmetros [i] .Direction;
Lista [i] .Attributes: = parâmetros [i] .Attributes;
fim
Finalmente
SetConnectionFlag (CFParameters, falso);
fim;
exceto
{Ignore o erro se o servidor não puder fornecer informações de parâmetro}
fim;
se list.count> 0 então
Parameters.assign (list);
fim;
Finalmente
List.Free;
fim;
fim;
Começar
if (commandType = cmdText) e (valor <> '') e paramcheck então
InitParameters
outro
Começar
CommandObject.CommandText: = value;
Se não estiver carregando, parameters.clear;
fim;
fim;
Dê uma olhada nesta declaração:
if (commandType = cmdText) e (valor <> '') e paramcheck então
InitParameters
Ou seja, quando o Paramcheck é verdadeiro, o processo InitParameters será executado.
Primeiro, ele define uma variável: nativeCommand: string;
NativeCommand: = list.parsesql (valor, true);
{Preserve os valores existentes}
List.assignValues (parâmetros);
CommandObject.CommandText: = nativEcommand;
Aqui, o valor é do tipo WideString e List.ParSesql Retorna Tipo de String, e o NativEnCommand também é o tipo de string. que faz com que o CommandObject.CommandText não obtenha o valor mais amplo que deve ser atribuído a ele, o que leva à ocorrência de código ilegal ao armazenar Unicode.
A solução também é muito simples (se você não estiver disposto a modificar o programa de origem Delphi), basta definir o ParamCheck como false (Delphi Padrats como paramcheck como true).