如何使用TADOCommand参数化查询参数化宽带?

时间:2012-05-24 15:35:05

标签: delphi ado delphi-5 parameterized-query

我正在尝试使用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:?\美尔小号\我值Σσn.A V`AŤöP I A \的p p d ??吨???????????????? ?\ L·O 6-8升?\ A v·在δπR' S 2 O F·T'W'AR? C·R·ΔT?我32 N 2 S'\ S 2 O°F T&瓦特?R 10 Q'ü?​​?李?吨?ÿ? M2 +吨·R·我?CS?\ C 17 S'-s Q +毫升00.x?毫升升


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

  

C̬:\Ȗŝḙr͇s̶\i̜ẵn̥.ÀV̹AͧT̶O̠P̩I̿Ȁ\A͜p̥p̔D͑ẫt̒ā\L̫o͋ɕălͭ\A̼v̼ẵt͈ấr̄S̫o̖f͎t̻w̵ạrẽC̾r̮ḛẵt̳̿͘͘͘ɇ̿ɇ̪̪̿ɇ̿ɇ̿ɇ̿ɇ̿ɇ̿ɇ̝̝̝̝̝̝̝̝̝̝̽̽̽̽̽̽̽̽̽̽̽̽̽̽̽̽

但它是very fragile and not suitable for production use

如何在Delphi中使用带TADOCommand的unicode / WideStrings?

Bonus Chatter

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

  

exec sp_executesql N'INSERT INTO Sqm(文件名)VALUES(@ P1)',N'@ P1 char(300),@ P2 text','C?:\ Us?er?s?\ i?än? .A·v·A·T'O 3 p'我?à\ A 2 p 2 p 2 d?在?一个\ L·O 3 CAL \ A v·在δπR'所以,F&T'W'AR? C?r ??á?i?o?n?s?\ So?f?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;

其中

  • NewValue是类型VT_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)

进行参数化的系列文章的一部分      

2 个答案:

答案 0 :(得分:0)

如何使用

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字符串吗?

答案 1 :(得分:0)

答案是在Delphi(5)中无法完成。

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

问。:如何使用TADOCommand参数化查询参数化宽字符串?
A。:你不能。对不起,很抱歉。