【问题标题】:How to parameterize widestrings using TADOCommand parameterized query?如何使用 TADOCommand 参数化查询参数化宽字符串?
【发布时间】:2012-05-24 15:35:04
【问题描述】:

我正在尝试使用 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?:\U?s?er?s?\i??n?.A?V`A?T?O?P?I?A?\A?p?p?D??t? ?\L?o???l?\A?v?at??r? S?o?f?t?w?är¨? C?r??t?i??n?s?\S?o°f?t?w?r?? Q?u??li?t?y? M??t?r?i?cs?\C??S?-s?q?m?00.x?m?l


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

c̬:\ ȗŝḙȗŝḙ͇͇ͧt̶o̠p̩̩̥̔͑ẫ͑ẫ̠̥̒̒͋ɕă͈ấ̄ę̨̨̨̨̨̨̖̖̖̻̻̳̬̬̖͎̻̳̬̬̖̬̻̻̻̻̻̻̻̻̃ͬͮ̽̽ͬ̽ͥ̽̽̽̽̽̽̽̽̽̽̽̽̽̽̽̽ͥ̽̽ͥͥͥ̽̽ͥͥ̽ͥͥͥͥͥͥ̚̚̚̚̕̚̚̚̕̚̕͜͜͜͜͜͜͜͜͜͜͜00.xͤm̧l̝l

但它是very fragile and not suitable for production use

如何在 Delphi 中将 unicode/WideStrings 与 TADOCommand 一起使用?

奖金聊天

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

exec sp_executesql N'INSERT INTO Sqm(Filename) VALUES(@P1)', N'@P1 char(300),@P2 text', 'C?:\Us?er?s?\i?än? .A?V?A?T?O?P?I?À\A?p?p?D?ât?a\L?o?cal¯\A?v?at??r?所以?f?t?w?ar?? C?r??á?i?o?n?s?\So¸f"t?w?ar?? Q?u??l?i?ty? M??t?r?i¸?s` \C?M°S?-s?q?m?00.?m¨´l¯'

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

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

ParameterObject.Value := NewValue;

在哪里

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

甚至试图强制参数类型:

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

没用。

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

【问题讨论】:

  • @RRUZ 从原始问题中删除了无关的recordsAffected 参数
  • 我不认为你尝试过 UTF-8,是吗?
  • Uch Delphi5,请继续使用支持 unicode 的 IDE/编译器
  • @whosrdaddy 我可以借到 20,000 美元

标签: delphi ado delphi-5 parameterized-query


【解决方案1】:

如何使用

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 server 2000可以处理UTF-32字符串吗?

【讨论】:

  • stringAnsiString的别名,不能保存unicode数据。我的 Delphi 版本中也没有 WideStringToUCS4String 函数。
  • 当将UCS4String 存储到变体中时,Delphi 会将其转换为 VarType。 COM 和 ADO 不支持UTF-32,并且变体无法容纳它们。
  • 嗨,Ian,我使用的是 Delphi 7,我可以在 System.pas 中找到 UCS-4 字符串或 UTF-32(Delphi 中的 UCS4String)以及函数 WideStringToUCS4String 和 UCS4StringToWidestring。
【解决方案2】:

答案是在Delphi中做不到(5)。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    相关资源
    最近更新 更多