2011-05-14 90 views
2

我知道這個問題已被問到before,但這些解決方案似乎不適用於我。在C#中創建並編譯「on the fly」存儲過程Net

我目前正試圖做到這一點:

  1. 建立甲骨文
  2. 使用企業庫5.0創建一個SQL命令「CREATE PROCEDURE」腳本字符串,並通過這個字符串作爲參數
  3. 有無保存在oracle數據庫中的程序

因此,第3點似乎工作到目前爲止,如果我打開SQL Developer並展開過程樹列表,那麼我實際上可以看到過程bu t與紅十字圈,這意味着它有編譯器錯誤,雖然運行這個相當小的代碼,在SQL Developer查詢窗口中工作正常並編譯它。我不確定在SQL Developer中做了些什麼,因爲運行該「CREATE PROCEDURE」腳本不會引發任何錯誤,然後我就可以看到並執行該過程,但不會從C#中完成。

我讀到在這個開始發佈的鏈接中,我應該調用IDBCommand.Prepare(),但該方法只與您的SQLCommand.CommandType是StoredProcedure類型有關,因爲我沒有實際調用過程,而是運行純sql爲了創建程序,這不起作用,但是,爲了測試,我創建了一個新的命令,我將其分配給StoredProcedure,然後在該命令上調用Prepare()方法,最後是拋出一個除非對象(存儲過程)不可用,這是合理的,因爲它尚未編譯...

所以,我想知道是否有人真的知道如何創建一個過程並從C#編譯它,我們是當前的儘管使用企業庫,但我不介意直接向Oracle提供者「硬編碼」,只要它能夠工作。

順便說一句,在告訴我從代碼創建一個過程是一個不好的做法我告訴你,不幸這是一個客戶的項目,我們沒有做出決定,實際上我們試圖從SQL Server遷移事情到Oracle。

+0

那麼,事實證明,由於某些原因,有回車字符(CR)或新行,如果你願意,在具有CREATE PROCEDURE命令的字符串導致這個問題,所以,不知何故,這是由oracle解釋錯誤地,誰知道什麼原因。無論如何,我「有點」通過做一個mySqlStr.Replace(System.Environment.NewLine,string.Empty)來解決它,這樣該命令進入一個單行,由10g Express正確解析。 – 2011-05-17 22:38:47

回答

2

我有點生疏,現在沒有Oracle訪問權限,但我想我知道你在問什麼。您想要使用ADO.NET OracleCommand類和Oracle EXECUTE IMMEDIATE語句。像這樣的:

 OracleConnection conn = new OracleConnection("Data Source=something; user id=something; Password=something;"); 
     conn.Open(); 
     OracleCommand command = new OracleCommand(); 
     command.CommandType = CommandType.Text; 
     command.CommandText = "execute immediate 'create or replace procedure [...you know this part...]' "; 
     command.Connection = conn; 
     command.ExecuteNonQuery(); 
     conn.Close(); 
    } 

這應該工作。但請注意,我總是使用ODP.NET(Oracle自己的數據提供者)而不是ADO.NET庫存,所以如果您僅使用庫存庫,可能會有一些細微的差異。

由於Pete建議您也可以使用動態SQL來達到同樣的效果。您將整個CREATE PROCEDURE語句作爲參數傳遞給現有的存儲過程,然後調用EXECUTE IMMEDIATE。不過我不相信你必須這樣做。如果你想保持最小化,以上應該工作。

另一件事。我不知道爲什麼會被髮生的事情,但如果甲骨文告訴你的程序是無效的,即使你知道這是很好,請嘗試執行

EXECUTE IMMEDIATE ALTER PROCEDURE schemaname.procedurename COMPILE; 

我經常發現甲骨文是一個有點脆弱與問候不必要地使對象失效。

+0

「EXECUTE IMMEDIATE CREATE OR REPLACE ...」不起作用,我的確在使用oracle自己的提供程序DLL ODAC – 2011-05-16 19:22:18

+0

對不起,您需要將執行的命令放在單引號中。固定。 – 2011-05-17 15:24:25

1

如果要在SQL Server或Oracle中動態執行DDL語句,必須將您在C#中創建的DDL傳遞給Oracle中的一個過程,然後使用EXECUTE IMMEDIATE將該字符串作爲命令運行並創建步驟。

來自Oracle的This page提到如果「您想要執行純靜態SQL程序中不支持的DDL語句和其他SQL語句」,則必須使用動態SQL。

我希望這可以幫助你。

+0

我認爲這是正確的答案,接受的答案不適用於我,這是。我無法使用ODP.NET創建存儲過程,除非我按照Pete提出的要求+1。 – shev72 2015-04-22 16:02:48

0

最後的字符是什麼?

Oracle的原始SQL * Plus使用斜槓字符來執行當前命令。許多IDE要麼使用相同的字符串,要麼將其解釋爲不作爲程序/程序包的一部分

因此,如果您在作爲CREATE ...字符串末尾的斜線(換行)那麼這將是一個錯誤。但是,如果由IDE加載並重新編譯,那麼IDE可能會爲您刪除它。

在C#加載之後檢查USER_ERRORS,看看是否有任何內容報告爲該程序單元的錯誤。

+0

最後沒有斜槓字符。 – 2011-05-16 19:23:16