Невозможно вставить Unicode в SQL Server 2008, используя Delphi ZeosLib и Delphi 7
У меня возникают проблемы при вставке Unicode в базу данных SQL Server с использованием Delphi ZeosLib и Delphi 7, а затем при чтении вставленного значения. Я создал простую тестовую программу, которая сначала вставляет, а затем запрашивает вставленное значение.
Схема тестовой таблицы:
CREATE TABLE [dbo].[incominglog](
[message] [nvarchar](500) NULL
) ON [PRIMARY]
Я загрузил простой источник тестовой программы (включая исходный код ZeosLib) - нажмите здесь, чтобы загрузить. Я также включил ntwdblib.dll, но вы можете использовать свой собственный.
Для тестовой программы также требуется компонент TNT, который можно скачать здесь
Используя тестовую программу, символы Unicode, которые я вставил, отображаются в виде вопросительных знаков при извлечении - я не уверен, связана ли проблема с кодом вставки или кодом запроса.
Я также пытался кодировать данные в utf-8 перед вставкой, а затем декодировать данные после извлечения из utf-8 - пожалуйста, найдите "// вставлен как utf8" в исходном тексте тестовой программы. Я могу просматривать Unicode после того, как он был декодирован, поэтому этот метод работает. Однако для моего реального приложения я не могу кодировать как UTF-8, так как SQL Server не полностью поддерживает UTF-8 - некоторые символы не могут быть сохранены. Смотрите мой предыдущий вопрос здесь.
Буду признателен за любые указатели.:)
Между тем, вот источник для тестовой программы:
unit Unit1;
interface
uses
ZConnection, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ZAbstractRODataset, ZAbstractDataset, ZAbstractTable, ZDataset,
StdCtrls, TntStdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
TntMemo1: TTntMemo;
Button2: TButton;
TntEdit1: TTntEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
FZConnection: TZConnection;
FZQuery: TZQuery;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
tntmemo1.Lines.Clear;
FZConnection := TZConnection.Create(Owner);
FZConnection.LoginPrompt := False;
FZQuery := TZQuery.Create(Owner);
FZQuery.Connection := FZConnection;
FZConnection.Protocol := 'mssql';
FZConnection.Database := 'replace-with-your-db';
FZConnection.HostName := 'localhost';
FZConnection.User := 'sa';
FZConnection.Password := 'replace-with-your-password';
FZConnection.Connect;
FZQuery.SQL.Text := 'SELECT * from incominglog';
FZQuery.ExecSQL;
FZQuery.Open;
FZQuery.First;
while not FZQuery.EOF do
begin
tntmemo1.Lines.add(FZQuery.FieldByName('message').AsString);
// tntmemo1.Lines.add(utf8decode(FZQuery.FieldByName('message').AsString)); //inserted as utf8
FZQuery.Next;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
sqlstring, data:widestring;
begin
FZConnection := TZConnection.Create(Owner);
FZConnection.LoginPrompt := False;
FZQuery := TZQuery.Create(Owner);
FZQuery.Connection := FZConnection;
FZConnection.Protocol := 'mssql';
FZConnection.Database := 'replace-with-your-db';
FZConnection.HostName := 'localhost';
FZConnection.User := 'sa';
FZConnection.Password := 'replace-with-your-password';
FZConnection.Connect;
data:= tntedit1.Text;
// data:= utf8encode(tntedit1.Text); //inserted as utf8
sqlstring:= 'INSERT INTO INCOMINGLOG ([MESSAGE]) VALUES(N''' + data + ''')';
FZQuery.SQL.Text := sqlstring;
FZQuery.ExecSQL;
end;
end.
1 ответ
Я не проверял ваш пример, но я могу без проблем сохранять и извлекать из базы данных символы Юникода на SQL Server с Delphi 7 VCL/CLX и zeoslib.
Я думаю, что в вашем случае будет достаточно изменить процедуру сохранения следующим образом:
procedure TForm1.Button2Click(Sender: TObject);
var
sqlstring : widestring;
data : UTF8String;
begin
FZConnection := TZConnection.Create(Owner);
FZConnection.LoginPrompt := False;
FZQuery := TZQuery.Create(Owner);
FZQuery.Connection := FZConnection;
FZConnection.Protocol := 'mssql';
FZConnection.Database := 'replace-with-your-db';
FZConnection.HostName := 'localhost';
FZConnection.User := 'sa';
FZConnection.Password := 'replace-with-your-password';
FZConnection.Connect;
data:= UTF8String( utf8encode(tntedit1.Text) );
sqlstring:= 'INSERT INTO INCOMINGLOG ([MESSAGE]) VALUES(:DATA)';
FZQuery.SQL.Text := sqlstring;
FZQuery.ParamByName('DATA').AsString := data;
FZQuery.ExecSQL;
end;
Смысл в том, чтобы изменить строковую переменную данных в типе UTF8String и использовать параметры для передачи строки данных в запрос... Честно говоря, я использую ее с командами ZTable и Post, но она должна быть такой же, как и у ZQuery, как у вас...