Search code examples
delphiutf-8firebirddelphi-10.2-tokyoeuro

UTF8, IBX and Firebird with Euro symbol


I am connecting to Firebird through IBX components in Delphi 10.2 Tokyo.

I'm trying to connect to the DB through the following code:

IBDatabase.Connected := False;
IBDatabase.Params.Clear;
IBDatabase.DatabaseName := FDBFileName;
IBDatabase.Params.Values['user_name'] := FDBUserName;
IBDatabase.Params.Values['password'] := FDBPassword;
IBDatabase.Params.Values['lc_ctype'] := 'UTF8';
IBDatabase.Connected := True;

By trapping the exception during connection, I can realize if the database does not exist, then I create it using the following code:

IBDatabase.Params.Clear;
IBDatabase.DatabaseName := FDBFileName;
IBDatabase.Params.Add('USER ''SYSDBA''');
IBDatabase.Params.Add('PASSWORD ''masterkey''');
IBDatabase.Params.Add('PAGE_SIZE 16384');
IBDatabase.Params.Add('DEFAULT CHARACTER SET UTF8');
IBDatabase.CreateDatabase;

The above operation creates the database and leaves the TIBDatabase component connected to the DB.

In this case, I am creating:

  • UTF8 string domains
  • Table with UTF8 field

and setting the Euro symbol () in it.

The app opens and the field is visible. When I restart the app I constantly get an error:

No mapping for the Unicode character exists in the target multi-byte code page


Solution

  • I decided to write this post in order to share the solution I found after almost a week and sleepless nights.

    The problem was generated by the creation of the database code. Since parameters are different and from the usual connection parameters I put DEFAULT CHARACTER SET UTF8, believing that any DDL or statement I was going to operate in the database had the UTF8 character set.

    This is not true, the database connection doesn't behave like the one with the lc_ctype parameter set.

    To solve this I just had to close connection to the database, reset the parameters like I did the first time:

    IBDatabase.Connected:= False;
    IBDatabase.Params.Clear;
    IBDatabase.DatabaseName:= FDBFileName;
    IBDatabase.Params.Values['user_name']:= FDBUserName;
    IBDatabase.Params.Values['password']:= FDBPassword;
    IBDatabase.Params.Values['lc_ctype']:= 'UTF8';
    IBDatabase.Connected:= True;
    

    and do all the operations. This way it works properly.