<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SOD框架使用金倉數(shù)據(jù)庫“踩坑記”

      SOD框架使用金倉數(shù)據(jù)庫“踩坑記”,嚴(yán)格來說是使用金倉數(shù)據(jù)庫過程的踩坑記,并不是使用SOD框架來訪問金倉數(shù)據(jù)庫才會發(fā)生的問題,SOD框架的網(wǎng)友多年前就封裝了人大金倉(現(xiàn)在已經(jīng)改名為“電科金倉”)和達(dá)夢數(shù)據(jù)庫的SOD框架數(shù)據(jù)提供程序,對應(yīng)的Nuget包名字分別是 PDF.NET.SOD.Dameng.Provider, PDF.NET.SOD.Kingbase.Provider ,所以當(dāng)我第一次使用金倉數(shù)據(jù)庫遇到問題時候疑惑為什么使用SOD框架會有問題,而別的ORM框架似乎沒有這樣的問題?

      第一個問題:神秘的sys_stat_scan_tables 角色

      SOD框架決定全面支持.NET6的時候,對金倉數(shù)據(jù)訪問提供程序也進(jìn)行了升級,使用的是Kdbndp 的Nuget包 8.0版本,正好它的說明也是只支持.NET6以上版本。升級后的SOD框架金倉數(shù)據(jù)訪問提供程序Nuget包ID為PWMIS.SOD.Kingbase.Provider ,使用它訪問最金倉V9數(shù)據(jù)庫的時候出現(xiàn)下面的問題:

      "22P02: invalid input value for enum information_schema.table_type_enum: \"FOREIGN\"\r\n\r\nPOSITION: 135"

      經(jīng)排查這個問題發(fā)生在調(diào)用ADO.NET的DbConnection的抽象方法GetSchema 方法有關(guān),可以使用下面的代碼進(jìn)行測試: 

      using Kdbndp;
      using System.Data;
      
      namespace KingbaseTest
      {
          internal class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine("Kingbase For .NET6 Access Test.");
                  string connStr = System.Configuration.ConfigurationManager.ConnectionStrings[1].ConnectionString;
                  Console.WriteLine(connStr);
                  using (KdbndpConnection conn = new KdbndpConnection(connStr))
                  {
                      conn.Open();
                      Console.WriteLine("Database Connected OK.");
                      DataTable dt = conn.GetSchema();
                      Console.WriteLine("GetScheme OK,Database has Schemas count:{0}",dt.Rows.Count);
                      DataTable dt2 = conn.GetSchema("Tables");
                      Console.WriteLine("Database has tables count:{0}", dt2.Rows.Count);
                      conn.Close();
                  }
                  Console.WriteLine("Test OK");
              }
          }
      }

      與金倉技術(shù)人員進(jìn)行多次溝通后,終于發(fā)現(xiàn)問題在金倉的MySQL數(shù)據(jù)庫兼容模式下,非System用戶訪問金倉數(shù)據(jù)庫的時候?qū)τ?information_schema.tables 對象沒有訪問權(quán)限:

      select table_schema FROM information_schema.tables  group by table_schema;

      提示用戶沒有訪問 sys_freespace 函數(shù)的權(quán)限:
      42501: permission denied for function sys_freespace

      出現(xiàn)這個問題的時候必須授權(quán)當(dāng)前訪問金倉數(shù)據(jù)庫的用戶有  sys_stat_scan_tables 角色。

      劃重點(diǎn):這個問題很很重要,當(dāng)你需要使用SOD框架的Code First編碼方式使用金倉數(shù)據(jù)庫的時候必須要確保用戶有 sys_stat_scan_tables 角色權(quán)限。

      劃重點(diǎn)這個問題僅出現(xiàn)在某些定制版的V8版本MySQL兼容模式中,V9版本沒有此問題

      第二個問題:令人迷惑的金倉驅(qū)動程序版本

      當(dāng)程序運(yùn)行在金倉為客戶定制的某V8版本的MySQL兼容模式數(shù)據(jù)庫上的時候,運(yùn)行上面這個測試程序又出現(xiàn)了下面的問題:

      System.ArgumentException
        HResult=0x80070057
        Message=A KingbaseES type with the name int16 was not found in the database
        Source=Kdbndp
        StackTrace:
         在 Kdbndp.Internal.KdbndpDatabaseInfo.GetKingbaseTypeByName(String pgName)
         在 Kdbndp.TypeMapping.BuiltInTypeHandlerResolver..ctor(KdbndpConnector connector)
         在 Kdbndp.TypeMapping.BuiltInTypeHandlerResolverFactory.Create(KdbndpConnector connector)
         在 Kdbndp.TypeMapping.ConnectorTypeMapper.Reset()
         在 Kdbndp.Internal.KdbndpConnector.<LoadDatabaseInfo>d__199.MoveNext()
         在 Kdbndp.Internal.KdbndpConnector.<Open>d__198.MoveNext()
         在 Kdbndp.ConnectorPool.<OpenNewConnector>d__34.MoveNext()
         在 Kdbndp.ConnectorPool.<<Get>g__RentAsync|31_0>d.MoveNext()
         在 Kdbndp.KdbndpConnection.<<Open>g__OpenAsync|47_0>d.MoveNext()
         在 Kdbndp.KdbndpConnection.Open()

      又是一個復(fù)雜的排查過程,在反復(fù)確認(rèn)了數(shù)據(jù)庫的版本之后,金倉技術(shù)人員找到了問題原因:驅(qū)動程序版本不正確。使用金倉公司指定的,對應(yīng)的Nuget包名字為 Kdbndp_V9 這個.NET驅(qū)動程序后問題果然解決。[文件下載]。于是,我不得不用這個驅(qū)動程序重新封裝了一個SOD框架訪問金倉數(shù)據(jù)庫的數(shù)據(jù)訪問提供程序,這就是為什么有PWMIS.SOD.Kingbase.Provider 了之后,還需要 PWMIS.SOD.Kingbase.Provider.Net6V9,PWMIS.SOD.Kingbase.Provider.Net8V9 兩個Nuget包的原因。簡單總結(jié)一下:

      1. PDF.NET.SOD.Kingbase.Provider --SOD框架適用于.NET 4.x 版本的金倉數(shù)據(jù)訪問提供程序;
      2. PWMIS.SOD.Kingbase.Provider --SOD框架適用于.NET 6以上,采用Kdbndp 8.0版本驅(qū)動程序,可以訪問金倉V8以及V9版本的數(shù)據(jù)庫;
      3. PWMIS.SOD.Kingbase.Provider.Net6V9 --SOD框架使用.NET 6版本的(也可以支持.NET 8),采用Kdbndp_V9 版本驅(qū)動程序,專為金倉V9版本和某些定制的V8版本數(shù)據(jù)庫訪問而定制的驅(qū)動程序,當(dāng)然也可以訪問V8版數(shù)據(jù)庫。
      4. PWMIS.SOD.Kingbase.Provider.Net8V9 --SOD框架使用.NET 8版本的,采用Kdbndp_V9 版本驅(qū)動程序,專為金倉V9版本而定制的驅(qū)動程序,可能不支持某些定制版本的V8版數(shù)據(jù)庫。

      綜上,你在具體使用金倉數(shù)據(jù)庫的時候需要使用哪個版本的SOD框架提供程序,可以根據(jù)情況測試后使用。

      劃重點(diǎn):如果你默認(rèn)使用金倉的Oracle兼容模式,就不會遇到上面兩個問題,直接使用PWMIS.SOD.Kingbase.Provider 驅(qū)動程序即可。

      為了方便在SOD框架中使用上述不同的驅(qū)動程序,可以添加一個應(yīng)用程序配置文件 app.config文件,在connectionStrings 配置節(jié)添加如下配置內(nèi)容:

       <connectionStrings>
        <!--
          <add name="local1" 
               connectionString="Server=127.0.0.1;User Id=system;Password=system;Database=test;Port=54321" 
               providerName="PWMIS.DataProvider.Data.Kingbase,PWMIS.KingbaseClient"/>
          <add name="local2"
               connectionString="Server=127.0.0.1;User Id=system;Password=system;Database=test;Port=54321"
               providerName="PWMIS.DataProvider.Data.Kingbase,PWMIS.KingbaseClient.Net6V9"/>
      -->
         <add name="default"
               connectionString="Server=127.0.0.1;User Id=system;Password=system;Database=test;Port=54321"
               providerName="PWMIS.DataProvider.Data.Kingbase,PWMIS.KingbaseClient.Net8V9"/>
        </connectionStrings>

      然后如下使用金倉數(shù)據(jù)訪問對象:

      PWMIS.DataProvider.Data.Kingbase kingbase= AdoHelper.CreateHelper("default");
      var dataset= kingbase.ExecuteDataSet("select * from [Table1] ");

       

      第三個問題:神秘的SQL_MODE

      像金倉、達(dá)夢這樣的國產(chǎn)化數(shù)據(jù)庫其誕生之初就號稱兼容Oracle,SQL Server,MySQL等市場常用的數(shù)據(jù)庫,聲稱可以無縫兼容基于這些數(shù)據(jù)庫開發(fā)的應(yīng)用,自然在使用金倉數(shù)據(jù)庫的時候會有數(shù)據(jù)庫兼容性的問題,而我們在通常使用中似乎真的沒有遇到兼容性問題,直到遇見了SQL-MODE問題。

      問題首先發(fā)生在應(yīng)用程序運(yùn)行在客戶定制的某金倉V8版本出現(xiàn)下面類似的錯誤:

       syntax error at or near ""Table1""
      CREATE SEQUENCE table1_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;
      CREATE TABLE "Table1"(
      "ID" integer DEFAULT nextval('table1_id_seq':regclass) NOT NULL PRIMARY KEY
      )

      很明顯,當(dāng)前數(shù)據(jù)庫不識別雙引號,Oracle數(shù)據(jù)庫對象使用雙引號進(jìn)行標(biāo)識,MySQL數(shù)據(jù)庫使用反單引號進(jìn)行標(biāo)識,由于當(dāng)前數(shù)據(jù)庫設(shè)置成MySQL兼容模式,上面創(chuàng)建表的語句自然報錯,正確的應(yīng)該是:

      CREATE SEQUENCE table1_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;
      CREATE TABLE `Table1`(
      `ID` integer DEFAULT nextval('table1_id_seq':regclass) NOT NULL PRIMARY KEY
      )

      為啥之前在測試的V9數(shù)據(jù)庫和V8數(shù)據(jù)庫都沒有遇到這個問題,在客戶定制的V8版本就出現(xiàn)這個問題了呢?請金倉的技術(shù)人員排查后發(fā)現(xiàn),原來兩個數(shù)據(jù)庫的SQL_MODE設(shè)置不一樣。

      SQL_MODE設(shè)置在數(shù)據(jù)庫運(yùn)行和SQL語句執(zhí)行中具有重要作用,它可以規(guī)范SQL語句的執(zhí)行行為,控制SQL語法的兼容性, 優(yōu)化查詢性能和安全性,控制數(shù)據(jù)完整性約束,影響數(shù)據(jù)類型和格式處理。SQL_MODE的默認(rèn)值為:

      SHOW SQL_MODE;
      
      ONLY_FULL_GROUP_BY,ANSI_QUOTES

      在默認(rèn)情況下,金倉數(shù)據(jù)庫會嚴(yán)格限制GROUP BY子句的使用,要求在SELECT列表中出現(xiàn)的非聚合列必須同時出現(xiàn)在GROUP BY子句中。金倉數(shù)據(jù)庫的SQL_MODE默認(rèn)值為ONLY_FULL_GROUP_BY。這意味著在默認(rèn)情況下,金倉數(shù)據(jù)庫會嚴(yán)格限制GROUP BY子句的使用,要求在SELECT列表中出現(xiàn)的非聚合列必須同時出現(xiàn)在GROUP BY子句中SQL_MODE設(shè)置為ANSI_QUOTES的作用是改變SQL語句中雙引號(")的語義,使其符合ANSI SQL標(biāo)準(zhǔn)。

      這也是為何在默認(rèn)情況下程序運(yùn)行沒有報錯的原因,然而客戶的數(shù)據(jù)庫中SQL_MODE設(shè)置為空,并且數(shù)據(jù)庫兼容模式為MySQL,所以在SQL查詢中對于表名字、字段名字必須使用反單引號。

      于是,SOD的金倉數(shù)據(jù)庫訪問提供程序也開啟了設(shè)置兼容模式:

      private string _DataBaseMode = "Oracle";
      private char _dbSplitChar = '"';
      /// <summary>
      /// 獲取或者設(shè)置數(shù)據(jù)庫兼容模式,可以指定的模式有Oracle,MySQL,SQLServer,PostgreSQL,默認(rèn)為Oracle
      /// </summary>
      public string DataBaseMode
      {
          get { return _DataBaseMode; }
          set
          {
              string mode = value.ToLower();
              if (mode == "oracle" || mode == "postgresql")
              {
                  _DataBaseMode = value;
                  _dbSplitChar = '"';
              }
              else if (mode == "mysql")
              {
                  _DataBaseMode = value;
                  _dbSplitChar = '`';
              }
              else if (mode == "sqlserver")
              {
                  _DataBaseMode = value;
                  _dbSplitChar = '[';//']'
              }
              else
              {
                  throw new Exception("Kingbase Database_mode must one is Oracle,MySQL,SQLServer.");
              }
          }
      }

      之后,在程序中這樣使用:

      var kingbase= new  PWMIS.DataProvider.Data.Kingbase();
      kingbase.ConntctionString="Server=127.0.0.1;User Id=system;Password=system;Database=test;Port=54321";
      kingbase.DataBaseMode="MySQL";
      var dataset= kingbase.ExecuteDataSet("select * from `Table1` ");

      注意:

      上面的示例方式是在SOD的金倉數(shù)據(jù)訪問提供程序 PWMIS.SOD.Kingbase.Provider.Net6V9 和 PWMIS.SOD.Kingbase.Provider.Net8V9 V6.0.1版本支持,如果使用 V6.0.0版本,可以全局設(shè)置,上面的示例代碼修改如下:

      var kingbase= new  PWMIS.DataProvider.Data.Kingbase();
      kingbase.ConntctionString="Server=127.0.0.1;User Id=system;Password=system;Database=test;Port=54321";
      //V6.0.0 版本使用靜態(tài)全局設(shè)置數(shù)據(jù)庫兼容模式:
      PWMIS.DataProvider.Data.Kingbase.DataBaseMode="MySQL";
      var dataset= kingbase.ExecuteDataSet("select * from `Table1` ");

       

      第四個問題:數(shù)據(jù)類型兼容的問題

      金倉V8以及V9各個版本的數(shù)據(jù)類型并不一定完全兼容,并且它與MySQL的類型也不完全兼容,因此建議在數(shù)據(jù)庫遷移的時候,一定要使用Code First方式,由程序自動創(chuàng)建表結(jié)構(gòu),否則遷移過程將有無盡的痛苦,這里不做過多表述。

      由于時間關(guān)系,先到這里。

       

      posted on 2025-07-06 18:38  深藍(lán)醫(yī)生  閱讀(388)  評論(1)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 亚洲国模精品一区二区| 国产专区一va亚洲v天堂| 国产精品人妻中文字幕| 福利一区二区不卡国产| 少妇无套内射中出视频| 婷婷六月天在线| 4hu44四虎www在线影院麻豆| 天堂网在线.www天堂在线资源| 国产精品午夜无码AV天美传媒| 亚洲 小说区 图片区 都市| 在线观看国产成人AV天堂| 精品人妻一区二区三区四区在线 | 亚洲欧美国产免费综合视频| 亚洲无人区码一二三四区| 中文激情一区二区三区四区| 成人无码h真人在线网站| 午夜射精日本三级| 精品国产女同疯狂摩擦2| 九九在线精品国产| 国产欧美在线观看不卡| 97se亚洲国产综合自在线观看| 国产又爽又黄的激情视频| 国产内射性高湖| 亚洲色成人网站www永久四虎| 日本免费一区二区三区久久| 亚洲中文字幕一区二区| 人妻系列无码专区免费| 天堂av网一区二区三区| 男女男免费视频网站国产| 国产精品久久中文字幕| 国产性三级高清在线观看| 久久月本道色综合久久| 先锋影音av最新资源| 亚洲精品国产精品国在线| 国产二区三区不卡免费| 日日噜噜夜夜爽爽| 蜜臀视频一区二区在线播放| 国产超碰无码最新上传| 久久久久国产精品熟女影院| 国产精品美腿一区在线看| 好深好湿好硬顶到了好爽|