2011-06-07 29 views
3

我一直在調用Oracle存儲過程,這些存儲過程在我的C#應用​​程序中返回RefCursors。示例存儲過程在下面給出。使用RefCursor編寫的聲明與存儲過程

CREATE OR REPLACE 
PROCEDURE "DOSOMETHING"(
    P_RECORDS OUT SYS_REFCURSOR) 
AS 
BEGIN 
    OPEN P_RECORDS FOR 
    SELECT SOMETHING FROM SOMETABLE; 
END; 

當使用OracleDataReader讀這個結果,每次該過程被稱爲數據庫分析的過程。經過一番搜索之後,我發現在使用RefCursor時,消除這種解析調用是不可能的。

但是,如果我只是使用準備語句調用過程如下,則可以避免此解析調用。

public void DoSomething() 
{ 
    var command = ServerDataConnection.CreateCommand(); 
    command.CommandType = CommandType.Text; 
    command.CommandText = "SELECT SOMETHING FROM SOMETABLE"; 
    command.Prepare(); 

    using (var reader = command.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
      DoSomethingToResult(); 
     } 
    } 
} 

我的問題是哪種方法對性能有最小的影響?是否將程序更改爲準備好的語句以避免解析調用對應用程序性能有更負面的影響?

請注意,這些select語句可以返回一大組結果。可能有成千上萬的行。

回答

1

在PL/SQL中使用引用遊標會在每次打開遊標時引發解析調用。每次您致電command.Prepare()時,都會發出相同的解析呼叫。現在,您的.NET代碼將像PL/SQL代碼一樣解析查詢。

如果您需要發出完全相同的查詢(只需更改參數),則可以在不需要額外解析調用的情況下重用命令對象。但是,這些解析將是軟解析,因此性能可能不明顯(大部分工作是在硬解析中完成的,這是數據庫首次遇到查詢時)。由於您的查詢返回了很多行,因此與實際獲取這些行的工作量相比,軟解析中涉及的工作量顯然可以忽略不計。

+0

是的,我做了這個改變,現在我的陳述沒有太多解析。是的,在實際的代碼中,我重用了我的命令對象。感謝您的迴應。 – 2011-06-09 04:16:47