在有Oracle數據庫C#項目中,有一個這樣的需求:在界面上配置了帶參數的PLSQL語句,但是要通過程序驗證其正確性,那麼該如何實現?這就是本文要探討的內容。
一:通過OracleCommand對象的ExecuteNonQuery方法驗證
這個方法要用到Oracle.ManagedDataAccess.dll,首先要將oracle客戶端目錄下的該文件拷貝的項目中並添加引用。可以在項目中新增一個驗證SQL語句的公共類並using。(例如:ValidateSQL.cs)
using Oracle.ManagedDataAccess.Client;
接下來可以在這個公共類中寫上一個通用的SQL驗證方法:
/// <summary> /// 驗證sql語句 /// </summary> /// <param name="sql"></param> /// <returns></returns> public bool ValidateSQL(string sql ,out string strmsg) { bool bResult; using (OracleConnection connection = new OracleConnection(this.connectionString)) { OracleCommand cmd = connection.CreateCommand(); connection.Open(); cmd.CommandText = "set autotrace traceonly"; //cmd.ExecuteNonQuery(); try { cmd.CommandText = sql; cmd.ExecuteNonQuery(); bResult = true; strmsg = "SQL語句驗證通過!"; } catch (Exception ex) { if (ex.Message.ToString().Contains("ORA-01008")) { //如果ORACLE錯誤號為未綁定變量,則說明語句正確 bResult = true; strmsg = "SQL語句驗證通過!"; } else { bResult = false; strmsg = "驗證出錯:" + ex.Message; } } finally { //cmd.CommandText = "set autotrace off"; //cmd.ExecuteNonQuery(); } } return bResult; }
一般情況下如果SQL語句中如果沒有帶參數,則可以直接驗證通過。如果存在參數,那麼則需要一些技巧,就是在catch中判斷錯誤號。
由於Oracle數據中對錯誤號的定義是固定的,不受版本號的影響。並且PLSQL腳本在執行的過程中,判斷參數的順序一半都靠後,往往是最後才會去判斷。
那麼如果語句有錯誤,會直接拋出來。如果錯誤號為“ORA-01008”,那麼說明變量沒有綁定。此時SQL語句一定是正確的。
此方法中要用到數據連接字符串,通過鏈接字符串重新創建OracleCommand對象來實現語句的驗證。
那麼,就會出現如下問題:如果字符串是加密的,那麼就會有無法正常建立連接,怎麼辦?
二:加密字符串的數據庫連接與SQL驗證
如果鏈接字符串是加密字符串,此時必須先解密再進行SQL腳本的判斷。如果此時調用上面的方法,直接進行判斷,會出現“鏈接字符串非法”,這樣的錯誤出現。
比如我的鏈接字符串是放在web.config的配置中,然後我配置了一個是否加密的節點,value為true表示加密,並給出了一個加密鏈接字符串。
<add key="ConStringEncrypt" value="true" /> <add key="ConnectionString" value="F4107C21837F889831795CA2637F77F119EE4F3108F882C0A8F27BE676B57C78B7AB9D8BFC406475A027E1FF2F2FF69626FCB0003F2D8BB99481EFC760A48FA6A2798764FE9D94E4" />
那麼此時通過OracleCommand對象的ExecuteNonQuery方法驗證語句時,就需要解密。代碼如下:
/// <summary> /// 獲取連接字符串 /// </summary> public static string ConnectionString { get { string _connectionString = ConfigurationManager.AppSettings["ConnectionString"]; //獲取是否加密的連接字符串的配置 string ConStringEncrypt = ConfigurationManager.AppSettings["ConStringEncrypt"]; if (ConStringEncrypt == "true") { //如果已加密,需要先解密(假設密鑰為dotnet,解密方法為Decrypt) _connectionString = Decrypt(_connectionString,"dotnet"); } return _connectionString; } }
將解密後的連接字符串帶入上面的方法中,在進行驗證就好了。效果如下圖所示:
注明:本文章為Healer007原創,署名:小蘿卜。如需轉載請注明出處!