@incendio, I think I figured it out (partly).
Because when I created a table in my own existing database, there was no problem.
When creating a new database with Lazarus/IBX, even with Firebird 2.5, it began having the problem.
I found out the CHARACTER SET of the database is the problem. If set to NONE, this problem occurs.
Here is a DDL of a problem database.
SET SQL DIALECT 3;
/* CREATE DATABASE '127.0.0.1:C:\Temp\TTT.FDB' PAGE_SIZE 4096 DEFAULT CHARACTER SET NONE */
/* Table: TBL, Owner: SYSDBA */
CREATE TABLE TBL (ID BIGINT NOT NULL,
S1 VARCHAR(32),
PRIMARY KEY (ID));
Same database without a problem:
SET SQL DIALECT 3;
/* CREATE DATABASE '127.0.0.1:C:\Temp\TTT2.FDB' PAGE_SIZE 4096 DEFAULT CHARACTER SET ISO8859_1 */
/* Table: TBL, Owner: SYSDBA */
CREATE TABLE TBL (ID BIGINT NOT NULL,
S1 VARCHAR(32),
PRIMARY KEY (ID));
(You can get the DDL with: isql -ex -u sysdba -p masterkey 127.0.0.1:C:\Temp\TTT.FDB )
Try to recreate your database with (or change) the CHARACTER SET ISO8859_1, and see if you still have the problem.
Now... it still remains a question for @tonyw why a database with CHARACTER SET NONE will exibit this behavior, but at least we are a step closer.Simple console app to select the data (and create the database if not found). Note, if run inside the IDE you need to click CONTINUE on the exception, to let it create the database (or you need to disable debugging or run outside the IDE).
Project > New Project > Simple project.
Ctrl + A (to select all) and paste in code below.
Project > Project Inspector and add ibnongui
(nothing else is required)
program simple_fb;
uses DB, IBDatabase, IBQuery, IB;
procedure foo;
const
Db = '127.0.0.1:C:\TEMP\TTT2.FDB';
Fld = 'S1';
Sql = 'SELECT S1 FROM TBL';
var
IB: TIBDatabase;
IbSql: TIBQuery;
procedure Exec(Str: String);
begin
IbSql.SQL.Text := Str;
IB.DefaultTransaction.Active := true;
IbSql.ExecSQL;
if IB.DefaultTransaction.Active then IB.DefaultTransaction.Commit;
end;
begin
IB := TIBDatabase.Create(nil);
IbSql := TIBQuery.Create(nil);
try
IB.DatabaseName := DB;
IB.DefaultTransaction := TIBTransaction.Create(IB);
IB.DefaultTransaction.DefaultDatabase := IB;
IB.LoginPrompt := false;
IbSql.Database := IB;
try
IB.Params.Clear;
IB.Params.Values['user_name'] := 'SYSDBA';
IB.Params.Values['password'] := 'masterkey';
IB.Params.Values['lc_ctype'] := 'NONE';
IB.Connected := True;
except
on E: EDatabaseError do
begin
if (E is EIBInterBaseError) and (EIBInterBaseError(E).IBErrorCode = 335544344) then
begin
IB.Params.Clear;
IB.Params.Add('USER ''SYSDBA''');
IB.Params.Add('PASSWORD ''masterkey''');
IB.Params.Add('PAGE_SIZE 4096');
IB.Params.Add('DEFAULT CHARACTER SET ISO8859_1');
IB.Params.Values['user_name'] := 'SYSDBA';
IB.Params.Values['password'] := 'masterkey';
IB.Params.Values['lc_ctype'] := 'ISO8859_1';
IB.SQLDialect := 3;
IB.CreateDatabase;
IB.Connected := false;
IB.Params.Clear;
IB.Params.Values['user_name'] := 'SYSDBA';
IB.Params.Values['password'] := 'masterkey';
IB.Params.Values['lc_ctype'] := 'ISO8859_1';
IB.Connected := True;
Exec('CREATE TABLE TBL (ID BIGINT PRIMARY KEY, S1 VARCHAR(32) );');
Exec('INSERT INTO TBL VALUES (1, ''One'');');
Exec('INSERT INTO TBL VALUES (2, ''Two'');');
Exec('INSERT INTO TBL VALUES (3, ''Three'');');
Exec('INSERT INTO TBL VALUES (4, ''Four'');');
end;
end;
end;
IB.DefaultTransaction.Active := true;
IbSql.SQL.Text := SQL;
IbSql.Open;
while not IbSql.EOF do
begin
writeln(IbSql.FieldByName(Fld).AsString);
writeln('Test: ' + IbSql.FieldByName(Fld).AsString);
writeln;
IbSql.Next;
end;
IbSql.Close;
finally
IbSql.Free;
IB.Free;
end;
end;
begin
foo;
ReadLn;
end.
When using DEFAULT CHARACTER SET NONE in above code... the problem creeps up again.