I had a very strange problem today. After a while I solved it, although still do not 100% understand it. I hope it can help someone later, reading it.
I had two very similar (freepascal, command line) programs, both working on the same database. I did insert/update with tSQLQuery using :param and Params.ParamByName('param').AsString := s;
In one of the programs UTF8 characters worked as it should, but in the other they did not. I tried all the tricks said in different places in the wiki/forum, like making a "set names 'utf8'", "set character set 'utf8'", set CharSet to 'UTF8', 'utf8', 'utf8mb4' but nothing worked.
I also tried that instead of using :param, just entering the value directly in the SQL.Text and then it works! Still this is not OK for SQL injection, so I went on.
Then I noticed that the working program had LazUtils as a dependency set, so I also made that, but still not working. Then I moved over the units used and when I added laz2_XmlRead then it started to work.
Since the second program does not do any XML activity, I thought it is one of the other units implicitly linked in when laz2_XmlRead is added, so logically I replaced it with lazutf8 and it works with that.
It is still strange to me, that even if I added uses lazutf8; to a units implementation section and the actual query is in another unit, it still works. So, it is clearly not a function calling reference (anyway the program compiles without LazUtils and lazutf8 as well), but a link time something.
So, this is the solution. Nonetheless, I would be happy if somebody could explain to me:
- why is it needed?
- why does any LazUtils unit work?
- How can it work from another unit?
- How is it possible that utf8 support works with SQL.Text but does not work with Params.ParamByName (unless LazUtils is linked)?