1

Im trying to insert emoji to my mysql. but it shows up as -> "??".

This is what I have done up until now.

My ASPX-page

<meta charset="utf-8">

My database table is set to:

 utf8mb4_unicode_ci

My database column is set to:

 utf8mb4_unicode_ci

My MySQL-connectionString:

server=mysql.server.com;uid=testuser;pwd=1234;database=testdb;convert zero datetime=True;charset=utf8mb4;

However, if I insert emoji directly with a sql-statement in phpMyAdmin it works perfectly

INSERT INTO Notification (id, headline, notificationText, sentDate) 
VALUES (null, 'test', '', NOW())

But when I try to insert by code (.NET C#) it shows up as "??".

private void EmojiQueryTester()
{
    string strSql = "INSERT INTO Notification (id, headline, notificationText, sentDate) " + 
                     " VALUES (null, 'test', '', NOW())";
    string strConnectionString = "mysql.server.com;uid=testuser;pwd=1234;database=testdb;" + 
                                 "convert zero datetime=True;charset=utf8mb4";

    using (var mySqlConnection = new MySqlConnection(strConnectionString))
    {
        mySqlConnection.Open();
        var mySqlCommand = new MySqlCommand(strSql, mySqlConnection);
        mySqlCommand.ExecuteNonQuery();
    }
}

enter image description here

id = 27 is inserted by my .NET code and id = 28 is inserted by phpMyAdmin

I have alså tried inserting other chars as followings, but still no luck:

U+1F601    |    \xF0\x9F\x98\x81     | 

SHOW CREATE TABLE Notification

CREATE TABLE `Notification` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `headline` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `notificationText` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
  `sentDate` date NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

enter image description here

SELECT notificationText, HEX(notificationText) FROM Notification

This is query of my encodings

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%' 

enter image description here

Print out of the HEX-string

public static string ConvertStringToHex(String input, System.Text.Encoding encoding)
{
    Byte[] stringBytes = encoding.GetBytes(input);
    StringBuilder sbBytes = new StringBuilder(stringBytes.Length * 2);
    foreach (byte b in stringBytes)
    {
        sbBytes.AppendFormat("{0:X2}", b);
    }
    return sbBytes.ToString();
}

protected void Page_Load(object sender, EventArgs e)
{
    string notification = "";

    DBTool dbT = new DBTool();
    dbT.tester(notification);

    Response.Write(ConvertStringToHex(notification, Encoding.UTF8));
}

output in browser: F09F9880

dbo.HEX(notification): 3F3F

dbo.notification: ??

So output in browser is basicly the corrent HEX for the smiley, however in dbo.HEX(notification) it converts into "3F3F". So basicly it writes in ASCII and not in UTF8 as it should do.

naak2803
  • 57
  • 8
  • Based off this, I would assume it's the C# not handling the emoji, but you probably already knew that – WhatsThePoint Jan 17 '20 at 10:16
  • Yes, that I know. Now the issue is, how to fix it... :D I'm assuming its my MySqlCommand that is not send the strSql in the corrent format or encoding, the question is, why?` – naak2803 Jan 17 '20 at 10:36
  • Each emoji usually has a code. Try using the code instead of actual character. – Aditya Bhave Jan 17 '20 at 10:40
  • I've tried using "U+1F601" and "\xF0\x9F\x98\x81", with no luck... same issue... its becomes "??" – naak2803 Jan 17 '20 at 10:52
  • @naak2803 I suspect it could be something the config file, can your check your `web.config` or `app.config`? – WhatsThePoint Jan 17 '20 at 10:56
  • Web.Config -> [link](https://pastecode.xyz/view/b0b4b51f) – naak2803 Jan 17 '20 at 12:09
  • What happens if you use `\u1f601` in your C# SQL string in place of the emoji? – Ian Kemp Jan 17 '20 at 13:02
  • 1
    @naak2803 the *fix* is to use UTF8 encoding in MySQL. Eg `ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin`. Instead of hard-coding the emoji in the field, pass it as a parameter too – Panagiotis Kanavos Jan 17 '20 at 13:07
  • @PanagiotisKanavos, still same issue... it becomes "??" – naak2803 Jan 17 '20 at 13:53
  • Please provide `SELECT col, HEX(col) ...` to see what is in the table now. – Rick James Jan 17 '20 at 18:42
  • Is it exactly 2 question marks? – Rick James Jan 17 '20 at 18:43
  • Please provide `SHOW CREATE TABLE Notification`. – Rick James Jan 17 '20 at 18:43
  • @RickJames, yes, one smily = 2 questions makes. – naak2803 Jan 19 '20 at 19:49
  • @RickJames Id int(11) NOT NULL AUTO_INCREMENT, headline varchar(255) COLLATE utf8mb4_bin NOT NULL, notificationText mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, sentDate date NOT NULL, PRIMARY KEY (Id) ) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci – naak2803 Jan 19 '20 at 20:12
  • Ditto: What happens when using *placeholders/parameters*? For the insert. Compare the DB afterwards and verify if the save was “as expected”. – user2864740 Jan 19 '20 at 20:26
  • Maybe relevant: `<%Response.charset="utf-8"%>`, `/etc/httpd/conf/httpd.conf`, `.htaccess` – Rick James Jan 19 '20 at 22:14
  • @RickJames tried adding <%Response.Charset = "utf-8";%>, did nothing much... "/etc/httpd/conf/httpd.conf, .htaccess " I dont have access to, since its on a external web host – naak2803 Jan 19 '20 at 23:26
  • @RickJames, I have update my original post with a new image showing the result of following query: "SELECT notificationText, HEX(notificationText) FROM Notification" _NOTE: the first row is inserted through phpmyadmin-gui, not my .net code._ – naak2803 Jan 21 '20 at 00:08
  • @naak2803 - The problem occurs as the `INSERT` is occurring. Can you get the hex of the string _before_ the insert, from within .net C# ? – Rick James Jan 21 '20 at 01:11
  • @RickJames see the updated post. I've now added HEX-string output. – naak2803 Jan 21 '20 at 11:23
  • We have a similar setup that works with the connection string using charset=utf8 What version of MySql are you on. I have tested this on 5.7 and 8.0 – Darryl Braaten Jan 23 '20 at 19:47
  • @DarrylBraaten version 4.9.4 – naak2803 Jan 24 '20 at 00:19

2 Answers2

2

Put this in the connection string:

id=my_user;password=my_password;database=some_db123;charset=utf8mb4;

Console.OutputEncoding = System.Text.Encoding.UTF8;

Server=myServerAddress;Database=myDataBase;Uid=myUsername;Pwd=myPassword; CharSet=utf8mb4;

And be sure the column in the table is CHARACTER SET utf8mb4.

For further debugging:

HEX('') in utf8mb4 is these 4 bytes: F09F988B
in utf16:  D83DDE0B
Rick James
  • 135,179
  • 13
  • 127
  • 222
0

My guess is that your .NET application has UTF-16 encoding. The two ?? corresponds to 2 bytes (16 bits).

Try encoding your string in UTF-8:

string sql = "... VALUES (null, 'test', '', NOW())";
byte [] bytes = Encoding.Default.GetBytes(sql);
string encoded = Encoding.UTF8.GetString(bytes);
// ...
var mySqlCommand = new MySqlCommand(encoded, mySqlConnection);

I'm not 100% sure, but all the rest you've showed us seems consistent.

Guillaume S.
  • 1,515
  • 1
  • 8
  • 21
  • Still the same outcome... two ?? – naak2803 Jan 19 '20 at 20:04
  • @naak2803 I rollbacked my answer. Can you try again with the updated code? I don't know what I was thinking but the answer you tried, I encoded from UTF32 to UTF16 which would not solve the issue, because I suspect that your .NET application is sending UTF16 and we want it to send UTF8 to your MySQL – Guillaume S. Jan 20 '20 at 16:41
  • sorry, still not working, and now åäö are not working either. input: "Kalle Anka är cool! " output: "Kalle Anka �r cool! ??" – naak2803 Jan 20 '20 at 23:24
  • Then I'd insert only a smiley with all the possible solutions you came with. And display your MySQL's column as binary data https://github.com/dbeaver/dbeaver/issues/2396 so that you can read exactly the bytes inserted, and see what is wrong/right. Don't hesitate to update your question with the interesting information. It's all I can think about for now – Guillaume S. Jan 21 '20 at 09:39