2014-02-28 60 views
1

我試圖在.NET中通過OracleDataReader執行下面的查詢,但是當我嘗試讀取column_expressions列的值時,我總是得到一個空字符串。Oracle的all_ind_expressionions視圖

SELECT ic.column_name, 
     ie.column_expression 
FROM all_ind_columns ic 
LEFT JOIN all_ind_expressions ie 
    ON ie.index_owner  = ic.index_owner 
    AND ie.index_name  = ic.index_name 
    AND ie.column_position = ic.column_position 
WHERE ic.index_owner  = 'owner_name' 
    AND ic.index_name  = 'index_name' 

我意識到,列id的數據類型爲LONG,但我不知道如果是這樣的原因。有沒有一種方法可以讀取列的實際值?

當我通過Oracle SQL開發人員執行相同的查詢時,我可以看到值。

回答

1

爲了能夠讀一列,它是LONG數據類型的OracleCommandInitialLONGFetchSize屬性必須被設置爲無零(默認零)值:

可惜你沒有提供您的.NET代碼,所以我給你一個C#+ ODP.NET非託管司機例如:

設置:

create table t1(
    col1 varchar2(11) 
); 

create index FBI on t1(upper(col1)); 

table T1 created. 
index FBI created. 

C#代碼:

string oraConnectionString = "Data source=nkpdb;User id=hr;password=password;"; 
OracleConnection oraConnection = new OracleConnection(oraConnectionString); 
oraConnection.Open(); 
/* Would be better to put this in a stored procedure */  
string sqlQuery = "select ic.column_name " + 
        "  , ie.column_expression " + 
        " from all_ind_columns ic " + 
        " left join all_ind_expressions ie " + 
        " on ie.index_owner  = ic.index_owner " + 
        " and ie.index_name  = ic.index_name " + 
        " and ie.column_position = ic.column_position " + 
        " where ic.index_owner = :INDOwner " + 
        " and ic.index_name = :INDName" ; 
OracleCommand oraCmd  = new OracleCommand(sqlQuery, oraConnection); 
OracleParameter indOwner = new OracleParameter("INDOwner", 
               OracleDbType.Varchar2); 
OracleParameter indName = new OracleParameter("INDName", 
               OracleDbType.Varchar2); 
indOwner.Value = "HR"; 
indName.Value = "FBI"; 
oraCmd.Parameters.Add(indOwner); 
oraCmd.Parameters.Add(indName); 
/* set up initial amount of data that the OracleDataReader 
* fetches for LONG column */ 
oraCmd.InitialLONGFetchSize = 1000; /* set initial size */ 
OracleDataReader oraDataReader = oraCmd.ExecuteReader(); 
if (oraDataReader.HasRows) 
{ 
    while (oraDataReader.Read()) 
    { 
     Console.WriteLine(oraDataReader.GetString(
           oraDataReader.GetOrdinal("column_expression"))); 
     } 
} 

結果:

enter image description here

默認情況下,InitialLONGFetchSize屬性設置爲0。這就是爲什麼你得到一個空字符串的原因。因此,您需要將此屬性設置爲大於零的值或將其設置爲-1以獲取整個LONG列。

+0

的InitialLONGFetchSize屬性設置所做的工作對我來說。我只關心它對查詢性能的任何影響。如果我確定返回的數據的長度不會超過100,那麼將值設置爲-1會對性能產生不利影響,而不是像100那樣設置顯式值? –

+0

@RahulVijayDawda不,在這種情況下,不應該有任何主要的表現處罰。但是,根據一般經驗,您將'InitialLONGFetchSize'設置爲比LONG值大一點的值,則80%(或更多)的行將返回。當然,將這個屬性設置爲-1並不是一個好主意,例如,如果LONG列的大小爲5Kb的行的95%和10Mb的行的5% - 總體響應時間將取決於該行5行的百分比。 –

0

這是另一個簡單的解決方案。

1 - 創建此功能

create or replace function Get_Text 
    (sINDEX_NAME in VARCHAR2, sIndex_owner in VARCHAR2, sColumn_position in VARCHAR2) 
    return varchar2 
is 
    Long_to_Varchar  varchar(32767); 
begin 
    select COLUMN_EXPRESSION into Long_to_Varchar 
     from SYS.all_ind_expressions 
     where INDEX_NAME = sINDEX_NAME and Index_owner=sIndex_owner and Column_position=sColumn_position; 
    return long_to_varchar; 
exception 
    when others then 
     return 'Error occurred'; 
end; 

2 - 使用此SQL

select ic.index_name, 
     ic.column_name, 
     GET_TEXT(Ie.INDEX_NAME,Ie.Index_owner,ie.Column_position) 
from all_ind_columns ic 
    left join all_ind_expressions ie 
    on ie.index_owner = ic.index_owner 
    and ie.index_name = ic.index_name 
    and ie.column_position = ic.column_position 
WHERE ic.index_owner  = 'owner_name' 
    AND ic.index_name  = 'index_name'