Apakah bug yang menyimpan Unicode di Delphi7?
Baru -baru ini, ketika menggunakan Delphi7 untuk melakukan program unicode, saya menemukan masalah seperti itu, yaitu ketika menggunakan komponen Tadocommand untuk menjalankan pernyataan SQL, jika ada karakter Unicode dalam pernyataan SQL, kode yang kacau akan muncul dalam database, dan hal yang sama adalah Benar untuk menggunakan ttntadoquery (penggunaan parameter tidak akan ada kode yang kacau, dan di sini kita hanya akan membahas metode SQL murni). Namun, Tadocommand sendiri mendukung lebar, dan properti CommandText juga dari jenis lebar. Mengapa masalah ini terjadi? Saya mencoba mengubah beberapa nilai atribut tadocommand dan menemukan fenomena aneh. Mengapa ini terjadi? Properti ini tampaknya tidak ada hubungannya dengan Unicode itu sendiri. Dengan mempelajari file adodb.pas di mana tadocommand berada, saya menemukan masalahnya.
Prosedur tadocommand.assignCommandText (nilai const: widestring; memuat: boolean);
Prosedur InitParameter;
var
I: Integer;
Daftar: TParameter;
NativeCommand: String;
Mulai
Daftar: = tParameters.create (self, tParameter);
mencoba
NativeCommand: = list.parsesql (nilai, true);
{Menjaga nilai yang ada}
List.assignValues (parameter);
CommandObject.CommandText: = NativeCommand;
Jika tidak memuat dan (ditugaskan (koneksi) atau (ConnectionString <> '')) maka
Mulai
mencoba
SetConnectionFlag (CFParameters, True);
mencoba
{Ambil info parameter tambahan dari server jika didukung}
Parameter.internalrefresh;
{Gunakan info parameter tambahan dari server untuk menginisialisasi daftar kami}
Jika parameter.count = list.count maka
untuk i: = 0 to list.count - 1 do
Mulai
Daftar [i] .datatype: = parameter [i] .datatype;
Daftar [i] .size: = parameter [i] .Size;
Daftar [i] .numericsCale: = parameter [i] .numericscale;
Daftar [i] .presisi: = Parameter [i] .presion;
Daftar [i] .direction: = parameter [i] .direction;
Daftar [i] .attributes: = parameter [i] .attributes;
akhir
Akhirnya
SetConnectionFlag (CFParameter, false);
akhir;
kecuali
{Abaikan kesalahan jika server tidak dapat memberikan info parameter}
akhir;
Jika list.count> 0 lalu
Parameter.assign (daftar);
akhir;
Akhirnya
Daftar. Gratis;
akhir;
akhir;
Mulai
if (commandType = cmdtext) dan (value <> '') dan paramcheck kemudian
Initparameters
kalau tidak
Mulai
CommandObject.CommandText: = value;
Jika tidak memuat maka parameter.clear;
akhir;
akhir;
Lihatlah pernyataan ini:
if (commandType = cmdtext) dan (value <> '') dan paramcheck kemudian
Initparameters
Artinya, ketika Paramcheck benar, proses initparameters akan dieksekusi.
Pertama, ini mendefinisikan variabel: NativeCommand: String;
NativeCommand: = list.parsesql (nilai, true);
{Menjaga nilai yang ada}
List.assignValues (parameter);
CommandObject.CommandText: = NativeCommand;
Di sini, nilainya adalah jenis lebar, dan daftar. Parsesql Mengembalikan tipe string, dan NativeCommand juga merupakan tipe string. yang menyebabkan commandObject.commandtext tidak mendapatkan nilai luas yang harus ditetapkan untuk itu, yang pada akhirnya mengarah pada terjadinya kode yang kacau saat menyimpan Unicode.
Solusinya juga sangat sederhana, (jika Anda tidak mau memodifikasi program Sumber Delphi) Anda hanya perlu mengatur Paramcheck menjadi false (Delphi default ke Paramcheck ke True).