单字节Oracle环境中的多字节字符存储(BLOB)和搜索(使用JSON函数)

单字节Oracle环境中的多字节字符存储(BLOB)和搜索(使用JSON函数),json,oracle,oracle12c,multibyte-characters,Json,Oracle,Oracle12c,Multibyte Characters,详情: Oracle数据库12c, 数据库版本:12.1.0.2.0 问题描述和要求: 第1部分: 我将JSON数据存储在NCLOB列中 我需要从JSON数据中搜索文本 考虑到性能,我可以选择使用数据类型BLOB,因为数据是JSON并且在BLOB列中。。我可以使用JSON索引全文搜索 当在BLOB列上使用JSON文本搜索索引进行搜索时,与在NCLOB上使用简单查询(LIKE)相比,性能显著提高,因此使用BLOB列 关于JSON搜索索引: JSON搜索索引是一种专门针对JSON数据的全文索引。 如

详情: Oracle数据库12c, 数据库版本:12.1.0.2.0

问题描述和要求:

第1部分:

  • 我将JSON数据存储在NCLOB列中
  • 我需要从JSON数据中搜索文本
  • 考虑到性能,我可以选择使用数据类型BLOB,因为数据是JSON并且在BLOB列中。。我可以使用JSON索引全文搜索
  • 当在BLOB列上使用JSON文本搜索索引进行搜索时,与在NCLOB上使用简单查询(LIKE)相比,性能显著提高,因此使用BLOB列

    关于JSON搜索索引:

    JSON搜索索引是一种专门针对JSON数据的全文索引。 如果数据库使用的是“强”字符集AL32 UTF8或WE8ISO859P1 < /强>,并且仅针对VARCHAR2、BLUB或CROB列中的JSON数据,<强>>NVARCHAR2和NCULB列< /强> < /P>,优化器将只考虑使用索引。 第2部分:

    我们有两种数据库类型,即单字节和多字节部署

    单字节字符集:

    NLS\u NCHAR\u字符集-->AL16UTF16, NLS_字符集----------->WE8MSWIN1252

    多字节的字符集:

    NLS\u NCHAR\u字符集-->AL16UTF16, NLS_字符集----------->AL32UTF8

    第3部分:

    在多字节部署中,我能够存储和搜索(使用JSON_TEXTCONTAINS)多字节文本,如“məharaːʂʈrə”。 原因:因为数据库使用了AL32UTF8字符集(BLOB列) 注意:JSON_TEXTCONTAINS仅适用于索引

    在单字节部署中,我无法存储相同的文本,即“məharaːʂʈrə”(因为它是多字节的,转换会导致数据丢失,如“m?hara???r”)

    问题: 如何在具有字符集WE8MSWIN1252的单字节部署的BLOB列中存储多字节数据,即“məharaːʂʈrə”

    < Oracle声明>:如果数据库使用的是“强”字符集AL32 UTF8或WE8ISO859P1 <强>,则优化器只考虑使用索引。 请注意,我能够在单字节环境中使用JSON搜索索引,即JSON_TEXTCONTAINS(用于简单搜索,即单字节)

    一旦我能够按原样存储数据,我将能够使用JSON_TEXTCONTAINS进行搜索

    示例代码(在单字节和多字节部署中都可以尝试: 请注意:这是多字节部署

    创建表:

    create table departments_json (
      department_id   integer not null primary key,
      department_data blob not null
    );
    
    数据应该是严格的Json(因此我们可以使用点表示法进行遍历):

    创建索引:

    create index deptj_ctx_ix 
      on departments_json (department_data)
        indextype is ctxsys.context     parameters ('section group  CTXSYS.JSON_SECTION_GROUP  sync (on commit)');
    
    插入简单json

    insert into departments_json 
      values ( 140, utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" : "məharaːʂʈrə"}]}'));
    
    如果出现任何错误(单字节),请将其转换为:

    insert into departments_json 
      values ( 140, UTL_RAW.convert(utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" : "məharaːʂʈrə"}]}'),'AL32UTF8','WE8MSWIN1252'));
    
    存储值:

    SELECT json_value(department_data format json, '$.department_list.value'  ) FROM departments_json JS WHERE DEPARTMENT_ID=140;
    
    观察:在单字节环境中会导致数据丢失

    现在搜索:

    SELECT *
    FROM   departments_json
    WHERE JSON_TEXTCONTAINS(department_data,  '$.department_list.value', 'məharaːʂʈrə');
    
    观察:多字节将产生行,但单字节将不产生行

    能够在单字节环境中使用JSON搜索索引,即JSON_TEXTCONTAINS(对于简单搜索,即单字节)--以下查询结果为一行:

    SELECT *
    FROM   departments_json
    WHERE JSON_TEXTCONTAINS(department_data,  '$.department_list.Deptname', 'DEPT-A');
    
    您可以通过.NET(C#)保存数据:

    有关.NET中的搜索结果:

    string h ="məharaːʂʈrə";    
    var read_command = orclCon.CreateCommand();
    read_command.CommandType = System.Data.CommandType.Text;
    read_command.Parameters.Add(new Oracle.ManagedDataAccess.Client.OracleParameter("searchText", System.Text.Encoding.GetEncoding("windows-1252").GetString(System.Text.Encoding.UTF8.GetBytes(h))));
    read_command.CommandText = "select * from departments_json JSON_TEXTCONTAINS(department_data,  '$.department_list.value', :searchText)";
    var dr = read_command.ExecuteReader();
    using (dr)
    {
      if (dr.HasRows)
      {
        while (dr.Read())
        {
          Oracle.ManagedDataAccess.Types.OracleBlob BLOB = dr.GetOracleBlob(1);
          var sr = new System.IO.StreamReader(BLOB);
          var content = sr.ReadToEnd();
        }
      }
    }
    
    在SQL中插入:

    insert into departments_json values (140, utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" :'|| UTL_RAW.convert("məharaːʂʈrə",'UTF8','WE8MSWIN1252')||'}]}'));
    
    SQL中的搜索结果:

    SELECT * FROM   departments_json WHERE JSON_TEXTCONTAINS(department_data, '$.department_list.value', CONVERT('məharaːʂʈrə', 'UTF8', 'WE8MSWIN1252'));
    
    您可以通过.NET(C#)保存数据:

    有关.NET中的搜索结果:

    string h ="məharaːʂʈrə";    
    var read_command = orclCon.CreateCommand();
    read_command.CommandType = System.Data.CommandType.Text;
    read_command.Parameters.Add(new Oracle.ManagedDataAccess.Client.OracleParameter("searchText", System.Text.Encoding.GetEncoding("windows-1252").GetString(System.Text.Encoding.UTF8.GetBytes(h))));
    read_command.CommandText = "select * from departments_json JSON_TEXTCONTAINS(department_data,  '$.department_list.value', :searchText)";
    var dr = read_command.ExecuteReader();
    using (dr)
    {
      if (dr.HasRows)
      {
        while (dr.Read())
        {
          Oracle.ManagedDataAccess.Types.OracleBlob BLOB = dr.GetOracleBlob(1);
          var sr = new System.IO.StreamReader(BLOB);
          var content = sr.ReadToEnd();
        }
      }
    }
    
    在SQL中插入:

    insert into departments_json values (140, utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" :'|| UTL_RAW.convert("məharaːʂʈrə",'UTF8','WE8MSWIN1252')||'}]}'));
    
    SQL中的搜索结果:

    SELECT * FROM   departments_json WHERE JSON_TEXTCONTAINS(department_data, '$.department_list.value', CONVERT('məharaːʂʈrə', 'UTF8', 'WE8MSWIN1252'));
    

    你可以试试u-escaping是否有效
    'm\u0259hara:\u0282\u0288r\u0259'
    。不知道。@JoopEggen谢谢你,我试过了,但没用。你可以试试u-escaping是否有效
    'm\u0259hara:\u0282\u0288r\u0259'
    。不知道。@JoopEggen谢谢你,我试过了,但没用。