首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Delphi 6处理Unicode字符

用Delphi 6处理Unicode字符
EN

Stack Overflow用户
提问于 2013-01-10 03:42:59
回答 2查看 6.7K关注 0票数 6

我有一个用Delphi 6开发的轮询应用程序,它读取文件,根据规范解析文件,执行验证并上传到数据库( Server 2008速成版)

我们必须为具有双字节字符集(DBCS)的操作系统提供支持,例如日本操作系统。因此,我们将Server中的数据库字段从varchar改为nvarchar。

轮询在DBCS操作系统中运行良好。如果系统区域设置为日文/中文/韩文,并且操作系统有相应的语言包,则它也可以成功地用于非DBCS操作系统。但是,如果区域设置为english,则数据库包含双字节字符的垃圾字符。

我做了一些测试,但没能识别出解决方案。

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

PFB样本代码:

代码语言:javascript
运行
复制
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操作系统中运行良好。

我试过玩弦乐、宽弦和UTF8String。但是,如果区域设置为English,则这在英语操作系统中不起作用。

请提供有关此问题的任何指示。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-10 11:56:00

在非Unicode Delphi版本中,您需要使用WideStrings (Unicode)而不是Strings (Ansi)。

忘记TADOQuery.SQL (TStrings),使用TADODataSet.CommandTextTADOCommand.CommandText(WideString)或作为TADODataSet的类型化TADOQuery。例如:

代码语言:javascript
运行
复制
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为true (默认情况下),则如果查询为Unicode (InitParameters为Ansi),则TADOCommand.SetCommandText->AssignCommandText将导致问题。

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

QuotedStr返回Ansi字符串。您需要此功能的宽版本(TNT)。

另外,正如“Arioch”所提到的TNT Unicode Controls套件是制作Delphi应用程序的最佳选择,它拥有成功管理应用程序中Unicode任务所需的所有控件和类。

简而言之,您需要考虑Wide :)

票数 4
EN

Stack Overflow用户

发布于 2013-01-10 08:54:58

  1. 您没有指定数据库服务器,因此此调查仍由我们进行。您应该检查您的数据库服务器如何支持Unicode。这意味着如何为数据库以及数据库中的表/列/索引/排序规则/等等指定Unicode字符集。您必须确保整个DB在每个细节上都启用了Unicode,以避免数据丢失。
  2. 通常,您还应该检查您的数据库连接(使用所选择的数据库访问库)是否也启用unicode。通常,微软ADO,就像和OLE一样,应该启用Unicode。但是,仍然要检查数据库服务器手册如何在连接字符串中指定unicode代码页或字符集。非Unicode连接也可能导致数据丢失。
  3. 当你告诉你读了一些unicode文件-它是模棱两可。什么尤斯unicode文件?是UTF-8吗?还是四种口味之一的UTF-16?还是-7?还是其他Unicode传输格式?通常的windows WideChar大致对应于遗留的UCS-2,并且预期是取消了英特尔-终端的UTF-16味道的BOM。http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069.aspx
  4. 如果该文件确实是UTF-16的味道,那么您可以使用德尔菲TWideStringList或绝地CodeLibrary TJclWideStringList加载它。检查您从未使用字符串变量处理数据的代码--使用WideString everywhere以避免数据丢失。 由于D6是最错误的版本之一,所以我更愿意确保安装了Delphi的每一个更新,然后安装和使用JCL。JCL还提供了代码页转换函数,这可能比普通的AnsiStringVar := WideStringVar方法更灵活。 对于UTF-8文件,它可以由JCL的TWideStringList类(但不是TJclWideStringList)加载。
  5. 调试时,将列表中的行加载到WideString变量,并确保它们的内容被保留。
  6. 不要写这样的查询。请参阅http://bobby-tables.com/,即使您不期望恶意破解-您可以自己制造错误或处理意外数据。使用参数化查询,在任何地方,每次!永远不要! 参见这样的示例:Parameters.html 检查每个SQL VARCHAR参数是否为ftWideString,以包含Unicode,而不是ftString。检查有关字段(列)的相同内容。
  7. 想一想,如果遗留技术可以被抛弃,因为它们的支持只会在时间上变得更加困难。由于不推荐Microsoft ADO (例如,更新版本的Microsoft SQL Server不支持它),请考虑切换到“实时”数据访问库。比如AnyDAC,UniDAC,ZeosDB或其他库。Torry.net可能暗示你在7.2左右。由于Delphi6RTL和VCL还没有准备好Unicode,所以考虑将应用程序迁移到TNT Unicode组件,如果您能够找到它们的免费版本或购买它们。或者迁移到较新的Delphi版本。由于Delphi6非常老,而且长期不受支持,而且它是Delphi中最错误的版本之一,因此考虑迁移到较新的Delphi版本或免费工具,如CodeTyphoon或Lazarus。更好的是,Lazarus在其最近的beta版本中开始使用Unicode,在迁移到它的最后,您可能会得到应用unicode的准备。7.4迁移可能是重新考虑应用程序和消除遗留意大利面的借口和刺激。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14250491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档