我正在尝试将参数化查询与 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
我可以使用本机参数化 ADOCommand
对象。它正确保存数据:
c̬:\ȗŝḙr͇s̶\i̜ẵn̥.àv̹aͧp̩i̿ȁp̩i̿ȁ\a͜p̥p̔d͑ẫ
但它非常脆弱,不适合生产使用。
我如何TADOCommand
在 Delphi 中使用 unicode/WideStrings?
奖金喋喋不休
在 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?çal¯\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;
在哪里
NewValue
是类型VT_BSTR
(akavarOleStr
) 的变体,具有适当的值ParameterObject
是本机 ADO_Parameter
对象,具有.Type
129 (adChar
)
甚至试图强制参数类型:
cmd.Parameters.ParamByName('filename').DataType := ftWideString;
cmd.Parameters.ParamByName('filename').Value := s;
没有帮助。
注意:这个问题是关于如何参数化的系列的一部分
INSERT INTO foo (value) VALUES (%s)