如何使用 TADOCommand 参数化查询参数化宽字符串



我正在尝试使用Delphi TADOCommand的参数化查询:

var 
   s: WideString;
   cmd: TADOCommand;  
   recordsAffected: OleVariant;
begin
   cmd := TADOCommand.Create(nil);
   cmd.Connection := Connection;
   cmd.CommandText := 'INSERT INTO Sqm(Filename) VALUES(:filename)';
   s := AFilename;
   cmd.Parameters.ParamByName('filename').Value := s;
   cmd.Execute();

数据库中的结果数据是完全破坏的:

C?:\美国?呃?\i??n?.一个?V'A?T?O?P?我?A?\A?p?p?D??t??\L?o???l?\A?v?at??r?S?o?f?t?w?är ̈?C?r??我??n?s?\S?o°f?t?w?r??问?u??啧?M??t?r?i?cs?\C??S?-s?q?m?00.x?m?l


可以使用本机参数化 ADO Command对象。它正确保存数据:

C̬:\Ŗŝḙrۇs̶\i̜ẵn̥.ÀV̹AۧT̶O̠P̩Í\Aۜp̥p̔Dۑẫt̒ā\L̫oۋɕălۭ\A̼v̼ẵtɈấr̄ S̫o̖fێt̻w̵ạrۂẽ C̾r̮ḛẵtۘi۩o̳n̬s̨\S̪ōf̒tۘw̿̚ɇ Q۬üẳl̮i̫tۥy̽ MۘŇt̨r̟i̻çš\CۍMۥS̚-s̞q̕mۜ00.xۤm̧l̝

但它非常脆弱,不适合生产使用。

如何在 Delphi 中使用 unicode/WideString with TADOCommand

奖金喋喋不休

在 SQL Server Profiler 中,您可以看到正在执行的 SQL:

exec sp_executesql n'插入到 sqm(文件名) 值 (@P1)', N'@P1 字符 (300),@P2 文本', 'C?:\Us?er?s?\i?än?.一个?V?A?T?O?P?I?À\A?p?p?D?ât?a\L?o?çal ̄\A?v?at??r?所以?f?t?w?ar??C?r??á?i?o?n?s?\so ̧f"t?w?ar??问?u??L?i?ty?M??t?r?i ̧?s'\C?M°S?-s?q?m?00.?米 ̈'l ̄ '

这指出了问题 - 它将WideString参数构建为char(300)值。让它不坏。

在进入参数洞之前,我最后一次看到我的 WideString 是:

ParameterObject.Value := NewValue;

哪里

  • NewValue 是具有适当值的 VT_BSTR 类型(又名 varOleStr)的变体
  • ParameterObject 是本机 ADO _Parameter对象,.Type为 129 (adChar

即使尝试强制参数类型:

cmd.Parameters.ParamByName('filename').DataType := ftWideString;
cmd.Parameters.ParamByName('filename').Value := s;

无济于事。

注意:这个问题是关于如何参数化INSERT INTO foo (value) VALUES (%s)的系列的一部分

  • https://stackoverflow.com/questions/10726212/using-wrong-type-with-parameterized-query-causes-error
  • 就 ADO 而言,nvarchar(max) 有多大?
  • 如何使用 TADOCommand 参数化查询参数化宽字符串?
  • ADO 参数化查询的"必须声明变量@myvariable"错误

如何使用

cmd.Parameters.ParamByName('filename').Value := WideStringToUCS4String(s);

顺便说一下,s 被声明为宽字符串。 是否有必要将 s 作为宽字符串?怎么样只是

var
  s : String; 

在 System.pas 中,UCS4String(UCS-4 字节或 UTF-32 位)声明为:

...
...
UCS4Char = type LongWord;
...
UCS4String = array of UCS4Char;
...
function WideStringToUCS4String(const S: WideString): UCS4String;
...
function UCS4StringToWidestring(const S: UCS4String): WideString;

您将文件名列存储为什么数据类型?sql 服务器 2000 可以处理 UTF-32 字符串吗?

答案是不能在德尔福(5)中完成。

它可能在较新版本的Delphi中得到修复;但是没有人测试它,我们将不知道。

问:如何使用 TADOCommand 参数化查询参数化宽字符串?
答:不能。很抱歉给您带来不便。

最新更新