一 前言 實戰踩坑系列,調用第三方Oracle存儲,各種血淚史,現記錄如下。 二 入坑 首先,調用Oracle需要安裝客戶端驅動才行,但是在程式開發中下載客戶端驅動是一個不明智的選擇。於是,不管是微軟,還是oracle,都提供了方便我們程式開發的插件(dll/nuget),如System.Data. ...
一 前言
實戰踩坑系列,調用第三方Oracle存儲,各種血淚史,現記錄如下。
二 入坑
首先,調用Oracle需要安裝客戶端驅動才行,但是在程式開發中下載客戶端驅動是一個不明智的選擇。於是,不管是微軟,還是oracle,都提供了方便我們程式開發的插件(dll/nuget),如System.Data.Oracle,Oracle.ManagedDataAccess。下圖搜索結果中Oracle.ManagedDataAccess.EntityFramework包含Oracle.ManagedDataAccess,適用於.net framework,如果你想要使用EF的話。因為這裡是NetCore程式,所以我選擇了Oracle.ManagedDataAccess.Core包。
初始程式:
private static void Remote() { // 創建Oracle連接 var connString = "User Id=user;Password=password;Data Source=ip:port/service_name;"; // 存儲過程名稱 var storedProcName = "SetTemperatureData"; // 參數設置 IDataParameter[] parameters = new IDataParameter[2]; parameters[0] = new OracleParameter("@id", 1);
parameters[1] = new OracleParameter("@date", DateTime.Now); parameters[2] = new OracleParameter("@result", OracleDbType.Decimal, ParameterDirection.Output); using (OracleConnection conn = new OracleConnection(connString)) using (OracleCommand command = BuildQueryCommand(conn, storedProcName, parameters)) { try { conn.Open(); var isSuccess = command.ExecuteNonQuery(); var result = (int)command.Parameters["@result"]; } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } private static OracleCommand BuildQueryCommand(OracleConnection connection, string storedProcName, IDataParameter[] parameters) { OracleCommand command = new OracleCommand(storedProcName, connection); command.CommandType = CommandType.StoredProcedure; foreach (OracleParameter parameter in parameters) { command.Parameters.Add(parameter); } return command; }
運行程式報錯:
錯誤1:
產生原因:對接方提供的鏈接是從庫地址,只有讀許可權。
錯誤2:
產生原因:存儲過程名稱問題,缺少了表空間,大概的意思是test.SetTemperatureData。
錯誤3:
產生原因:入參格式問題,字元串類型和時間類型不統一導致。
錯誤4:
產生原因:(int)command.Parameters["@result"]不能直接轉換,需要進行多次轉換Convert.ToDecimal(((OracleDecimal)command.Parameters["@result"].Value).Value);
錯誤5:
產生原因:瞭解到第三方oracle採用的是分散式負載均衡的方式,提供了多個ip地址,那原有的鏈接方式就不適用了,需要採用tsname.oa的方式鏈接。
錯誤6:若你由於粗心大意,也會有所收穫
產生原因:鏈接字元錯誤,請仔細檢查
三 出坑
簡直是錯誤大全,哈哈!最後代碼粘貼如下:
private static void Remote() { // 創建Oracle連接 var connString = "User ID=uer;Password=password;Data Source=test"; if (string.IsNullOrWhiteSpace(OracleConfiguration.OracleDataSources["test"])) { OracleConfiguration.OracleDataSources.Add("test", "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=[ip1])(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=[ip2])" + "(PORT=1521))(LOAD_BALANCE=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=service_name))))"); } // 存儲過程名稱 var storedProcName = "test.StoredProcName"; // 參數設置 IDataParameter[] parameters = new IDataParameter[3]; parameters[0] = new OracleParameter("@id", 1); parameters[1] = new OracleParameter("@date", DateTime.Now); parameters[2] = new OracleParameter("@result", OracleDbType.Decimal, ParameterDirection.Output); using (OracleConnection conn = new OracleConnection(connString)) using (OracleCommand command = BuildQueryCommand(conn, storedProcName, parameters)) { try { conn.Open(); var isSuccess = command.ExecuteNonQuery(); var result = Convert.ToDecimal(((OracleDecimal)command.Parameters["@result"].Value).Value); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } }