如何Unicode数据保存到Oracle?(How to save unicode data to

2019-06-27 00:09发布

我想保存在Oracle数据库(10克)Unicode数据(希腊)。 我创建了一个简单的表:

据我所知,NVARCHAR2总是使用UTF-16编码所以它必须是罚款所有(人)语言。

然后我试图插入数据库的字符串。 我已经硬编码串码(“你好吗?”在希腊文)。 然后,我设法得到它从数据库返回并显示它。

class Program
{
    static string connectionString = "<my connection string>";

    static void Main (string[] args) {
        string textBefore = "Τι κάνεις;";

        DeleteAll ();
        SaveToDatabase (textBefore);
        string textAfter = GetFromDatabase ();

        string beforeData = String.Format ("Before: {0}, ({1})", textBefore, ToHex (textBefore));
        string afterData = String.Format ("After: {0}, ({1})", textAfter, ToHex (textAfter));

        Console.WriteLine (beforeData);
        Console.WriteLine (afterData);

        MessageBox.Show (beforeData);
        MessageBox.Show (afterData);

        Console.ReadLine ();
    }

    static void DeleteAll () {
        using (var oraConnection = new OracleConnection (connectionString)) {
            oraConnection.Open ();
            var command = oraConnection.CreateCommand ();

            command.CommandText = "delete from UNICODEDATA";
            command.ExecuteNonQuery ();
        }            
    }

    static void SaveToDatabase (string stringToSave) {
        using (var oraConnection = new OracleConnection (connectionString)) {
            oraConnection.Open ();
            var command = oraConnection.CreateCommand ();

            command.CommandText = "INSERT into UNICODEDATA (ID, UNICODESTRING) Values (11, :UnicodeString)";
            command.Parameters.Add (":UnicodeString", stringToSave);
            command.ExecuteNonQuery ();
        }
    }

    static string GetFromDatabase () {
        using (var oraConnection = new OracleConnection (connectionString)) {
            oraConnection.Open ();

            var command = oraConnection.CreateCommand ();
            command.CommandText = "Select * from UNICODEDATA";
            var erpReader = command.ExecuteReader ();

            string s = String.Empty;
            while (erpReader.Read ()) {
                string text = erpReader.GetString (1);
                s += text + ", ";
            }

            return s;
        }
    }

    static string ToHex (string input) {
        string bytes = String.Empty;
        foreach (var c in input)
            bytes += ((int)c).ToString ("X4") + " ";

        return bytes;
    }
}

下面是不同的输出:

在消息框中发送到数据库之前,文本:

在消息框中,从数据库中获取后的文字:

控制台输出:

请你可以建议我可能是错在这里做什么?

Answer 1:

我可以看到问题的五种可能的地区:

  1. 你是如何真正去文成.NET应用程序? 如果在STRING的硬编码的文字,你确定编译器承担源文件正确的编码?

  2. 有可能是你怎么想发送给数据库中的问题。

  3. 有可能是与它如何被存储在数据库中的一个问题。

  4. 有可能是与你怎么在数据库中获取它的一个问题。

  5. 有可能是与如何你又显示它以后的问题。

现在地区2-4声音就像他们就不太可能是一个问题比1和5你怎么算账显示的文本? 你居然取出来在.NET数据库,或者您使用的蟾蜍或类似的东西来尝试看看吧?

如果你再从.NET编写出来的,我建议你跳过数据库完全 - 如果你只是显示字符串本身,你怎么看?

我中有你可能会发现在有用的文章调试Unicode的问题 。 特别是集中在其中编码可以走错了每一个地方,并确保当你“显示”为你倾倒出确切的Unicode字符(如整数),这样你就可以检查这些,而不是仅仅不管你当前字体想要一个字符串显示。

编辑:好的,所以数据库某处问题所涉及。

强烈建议你删除像ASP和HTML东西的方程。 写一个简单的控制台应用程序, 什么也不 ,但插入的文本,并再次把它拿来。 使其前后转储个人Unicode字符(如整数)。 然后尝试,看看有什么在数据库中(例如,使用蟾蜍)。 我不知道甲骨文功能字符串转换成单独的Unicode字符序列,然后转换这些字符为整数,但是这将很可能是未来的事情我会尝试。

编辑:两个以上建议(很好看的控制台应用程序,顺便说一句)。

  1. 指定参数的数据类型,而不是只给它的对象。 例如:

     command.Parameters.Add (":UnicodeString", OracleType.NVarChar).Value = stringToSave; 
  2. 考虑使用Oracle自己的驱动程序,而不是一个内置到.NET的。 你可能想反正要做到这一点,因为它通常总计是更快,更可靠的,我相信。



Answer 2:

你可以决定哪些字符集数据库使用的NCHAR与查询:

SQL> SELECT VALUE
  2    FROM nls_database_parameters
  3   WHERE parameter = 'NLS_NCHAR_CHARACTERSET';

VALUE
------------
AL16UTF16

检查你的数据库配置是正确的,你可以运行在SQL以下*加:

SQL> CREATE TABLE unicodedata (ID NUMBER, unicodestring NVARCHAR2(100)); 

Table created
SQL> INSERT INTO unicodedata VALUES (11, 'Τι κάνεις;');

1 row inserted
SQL> SELECT * FROM unicodedata;

        ID UNICODESTRING
---------- ---------------------------------------------------
        11 Τι κάνεις;


Answer 3:

还有一两件事值得一提。

如果您正在使用Oracle客户端,并希望包括在CommandText Unicode字符,你应该folloing行添加到您的应用程序的启动:

System.Environment.SetEnvironmentVariable("ORA_NCHAR_LITERAL_REPLACE", "TRUE");

这将允许你,如果你需要它,使用的语法如下:

command.CommandText = "INSERT into UNICODEDATA (ID, UNICODESTRING) Values (11, N'Τι κάνεις;')";


Answer 4:

一些调查后,在这里我们去:

字符串输入= “•”; 炭S =输入[0];

       //table kuuku with column kuku(nvarchar2(100))
        string connString = "your connection";

        //CLEAN TABLE
        using (System.Data.OracleClient.OracleConnection cn = new System.Data.OracleClient.OracleConnection(connString))
        {
            cn.Open();
            System.Data.OracleClient.OracleCommand cmd = new System.Data.OracleClient.OracleCommand("delete from  kuku ", cn);
            cmd.ExecuteNonQuery();
            cn.Close();
        }


        //INSERT WITH PARAMETER BINDING - UNICODE SAVED
        using (System.Data.OracleClient.OracleConnection cn = new System.Data.OracleClient.OracleConnection(connString))
        {
            cn.Open();
            System.Data.OracleClient.OracleCommand cmd = new System.Data.OracleClient.OracleCommand("insert into  kuku (kuku) values(:UnicodeString)", cn);
            cmd.Parameters.Add(":UnicodeString", System.Data.OracleClient.OracleType.NVarChar).Value = input + " OK" ;
            cmd.ExecuteNonQuery();
            cn.Close();
        }

        //INSERT WITHOUT PARAMETER BINDING - UNICODE NOT SAVED
        using (System.Data.OracleClient.OracleConnection cn = new System.Data.OracleClient.OracleConnection(connString))
        {
            cn.Open();
            System.Data.OracleClient.OracleCommand cmd = new System.Data.OracleClient.OracleCommand("insert into  kuku (kuku) values('" +input+" WRONG')", cn);
            cmd.ExecuteNonQuery();
            cn.Close();
        }
        //FETCH RESULT
        using (System.Data.OracleClient.OracleConnection cn = new System.Data.OracleClient.OracleConnection(connString))
        {
            cn.Open();
            System.Data.OracleClient.OracleCommand cmd = new System.Data.OracleClient.OracleCommand("select kuku from kuku", cn);
            System.Data.OracleClient.OracleDataReader dr = cmd.ExecuteReader();
            if(dr.Read())
            {
                string output = (string) dr[0];
                char sa = output[0];
            }
            cn.Close();
        }
    }



Answer 5:

在阅读记录,尝试

Encoding utf = Encoding.Default;   
var utfBytes = odatareader.GetOracleString(0).GetNonUnicodeBytes();//OracleDataReader
Console.WriteLine(utf.GetString(utfBytes));


Answer 6:

解决方案:设置NLS_LANG!

详细信息:我刚刚有同样的问题,而实际上有确切作为谢尔盖Bazarnik的调查描述了同样的情况。 使用绑定变量它的工作原理,没有他们就没有。

解决的办法是设置NLS_LANG在适当的位置。 因为我有Windows服务器我将它设置在Windows注册表下HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_OraClient11g_home1

请注意,regitry位置可能difer所以最简单的方法是搜索注册表“ORACLE_HOME”字符串。 其它系统也如Linux,UNIX可以设置此不同的方式(出口NLS_LANG ...)

在我来说,我把"NLS_LANG"="CROATIAN_CROATIA.UTF8" 。 因为我没有这个变量设置它去为缺省值。 更改注册表后,你应该重新启动过程。 在我的情况,我重新启动IIS。

至于原因,这与绑定变量的作品可能是因为它实际上发生在服务器端,而没有它实际上是在客户端发生。 因此,即使是DB可以插入正确的价值观 - 在这之前发生,客户端确实不需要的修正,因为它认为这是应该做的。 这是因为NLS_LANG默认为简单的代码页。 但是在做有用的任务,这产生了一个问题,它(如图调查看起来很难理解)。

如果您有多个Oracle版本,一定要纠正注册表中的所有版本(在我的情况甲骨文10例有效设置,但甲骨文11没有NLS_LANG设置的话)。



文章来源: How to save unicode data to oracle?