处理采用Delphi 6 Unicode字符的(Handling of Unicode Charac

2019-07-18 01:11发布

我公司开发的投票应用程序在Delphi 6,读取文件,根据规范解析该文件,执行验证并上传到数据库(SQL Server 2008 Express的版

我们必须提供具有双字节字符集(DBCS),如日本OS操作系统的支持。 所以,我们改变了在SQL Server数据库字段从varchar到nvarchar的。

轮询操作系统工作正常DBCS。 它也成功的非DBCS操作系统上,如果系统区域设置为日语/中国/韩国和操作系统具有相应语言包。 但是,如果该区域设置为英语,然后,该数据库包含双字节字符垃圾字符。

我进行了一些测试,但没有找出解决方案。

例如,如果我从使用的TStringList一个UTF-8文件中读取并保存到另一个文件,然后,Unicode数据将被保存。 但是,如果我用文件的内容来运行使用TADOQuery组件然后更新查询,垃圾字符显示。 该数据库还包含垃圾字符。

PFB示例代码:

var
    stlTemp : TStringList;
    qry : TADOQuery;
    stQuery : string;
begin
    stlTemp := TStringList.Create;
    qry := TADOQuery.Create(nil);
    stlTemp.LoadFromFile('D:\DelphiUnicode\unicode.txt');
    //stlTemp.SaveToFile('D:\DelphiUnicode\1.txt'); // This works. Even though 
    //the stlTemp.Strings[0] contains junk characters if seen in watch

    stQuery := 'UPDATE dbo.receivers SET company = ' + QuotedStr(stlTemp.Strings[0]) +
        ' WHERE receiver_cd = N' + QuotedStr('Receiver'); 
    //company is a nvarchar field in the  database
    qry.Connection := ADOConnection1;
    with qry do
    begin
        Close;
        SQL.Clear;
        SQL.Add(stQuery);
        ExecSQL;
    end;
    qry.Free;
    stlTemp.Free
end;

上面的代码在DBCS操作系统工作正常。

我曾尝试用绳子,WideString的UTF8字符串和播放。 但是,这并不在英文操作系统如果区域设置为英语的工作。

请提供这个问题的任何指针。

Answer 1:

在非Unicode的德尔福版本,其基本用法就是你需要使用的WideString S(Unicode)的,而不是String S(ANSI)。

忘掉TADOQuery.SQL (字符串列表),并与工作TADODataSet.CommandTextTADOCommand.CommandText (WideString的)或强制转换TADOQueryTADODataSet 。 例如:

stlTemp: TWideStringList; // <- Unicode strings - TNT or other Unicode lib
qry: TADOQuery;
stQuery: WideString; // <- Unicode string

TADODataSet(qry).CommandText := stQuery;
RowsAffected := qry.ExecSQL;

您还可以使用TADOConnection.Execute(stQuery)直接执行查询。


要格外小心参数化查询: ADODB.TParameters.ParseSQL是ANSI。 如果ParamCheck为真(默认) TADOCommand.SetCommandText - > AssignCommandText会造成问题,如果您的查询是Unicode( InitParameters是ANSI)。

(请注意,您可以使用ADO Command.Parameters直接-使用?字符作为占位符参数,而不是德尔福的约定:param_name )。


QuotedStr返回ANSI字符串。 你需要这个功能的宽版(TNT)


此外,由于@Arioch“所提到的TNT Unicode Controls套件是您的最佳炸制作德尔福Unicode应用程序。 它拥有所有的控制,你需要在你的应用程序成功地管理Unicode的任务类。

总之,你需要认为:)



Answer 2:

  1. 您没有指定的数据库服务器,所以这次调查仍然在我们的一部分。 您应该检查怎么做你的数据库服务器支持Unicode。 这意味着如何指定UNICODE字符集数据库和表/列/索引/排序/等里面。 你必须确保整个DB是在每一个细节其普遍地支持Unicode,以避免数据丢失。

  2. 一般来说,你还应该检查你的数据库连接(使用选择的数据库访问库)也支持Unicode。 一般来说微软ADO,只是喜欢和OLE,应该支持Unicode。 但还是检查你的数据库服务器手册如何指定连接字符串中的Unicode代码页或字符集。 非Unicode连接也可能导致数据丢失。

  3. 当你告诉你读一些Unicode文件 - 它是模糊的。 什么IUS Unicode文件? 它是UTF-8? 的UTF-16的四种口味还是一个? 或UTF-7? 或者一些其他的Unicode格式运输? 平时窗户WideChar大致对应于传统的UCS-2,预计是UTF-16的BOM-剥离英特尔-Endian的味道。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069.aspx

  4. 如果文件肯定是UTF-16的那个味道,那么你可以用Delphi加载它TWideStringList或绝地CodeLibrary TJclWideStringList 。 检查你的代码,你从来没有使用字符串变量来处理数据 - 使用WideString的处处以避免数据丢失。
    由于D6是buggiest版本之一,我宁愿以确保安装每次更新德尔福,然后安装并使用JCL。 JCL还提供代码页转换函数,这可能是比普通更灵活AnsiStringVar := WideStringVar方法。
    对于UTF-8的文件,它可以通过加载TWideStringList类JCL(但不是TJclWideStringList )。

  5. 在调试时,列表中的负载线WideString变量,并看到他们的内容被保留。

  6. 不要写这样的疑问。 见http://bobby-tables.com/即使你不希望恶意的黑客-你可以自己做出错误或肉意外的数据。 使用参数化查询,无处不在,每一次! EVER!
    看到的这样的示例: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/ADODB_TADOQuery_Parameters.html
    检查每一个SQL VARCHAR参数就会ftWideString到包含Unicode,不ftString 。 检查有关字段(列)相同。

  7. 认为,如果传统技术可以一边浇注,因为他们的支持,只会在时间上会更加困难。

    7.1。 由于微软ADO被弃用(用于exampel的Microsoft SQL Server的新版本将不支持它),考虑切换到“实时”数据访问库。 像AnyDAC,UniDAC,ZeosDB或其他一些库。 Torry.net可能会提示你一些。

    7.2。 自从Delphi 6 RTL和VCL是不是Unicode的准备,考虑你的应用程序迁移到TNT Unicode的组件,如果你设法找到他们的免费版本或购买。 或迁移到新的德尔福释放。

    7.3。 由于德尔福6很老长不支持,并因为它是buggiest德尔福的一个版本中,考虑迁移到新版本的Delphi或免费的工具,如CodeTyphoon或拉撒路。 作为奖励,拉撒路开始移动到Unicode在其最近的beta版本,并且可以通过移植到它的最后,你会得到你的应用程序Unicode的准备。

    7.4迁移可能是借口,刺激了重新分解您的应用程序,摆脱传统的意大利面条。



文章来源: Handling of Unicode Characters using Delphi 6