![](/img/trans.png)
[英]ODP.NET How to pass array of strings to an Oracle Stored procedure?
[英]Passing array of raw(32) argument to Oracle Stored Procedure in ODP.NET
我有一個自定義類型和存儲過程定義如下:
CREATE OR REPLACE TYPE GuidArray is varray(1000) of RAW(32);
/
CREATE OR REPLACE
PROCEDURE BulkInsertTempItemGuid
(
ItemGuidList IN GuidArray default null
) AS
BEGIN
--
-- procedure body here
--
END;
/
我試圖從ac#application在Oracle的ODP .NET中調用這個存儲過程。 我似乎很想正確地設置我的OracleParameter
,因為Oracle告訴我我沒有向它發送正確的參數集。 我正在設置CollectionType,OracleDbType和Value,如下所示。 parameters
是一個OracleParameter
和arrangedGuidList
是IEnumerable<Guid>
parameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
parameter.OracleDbType = OracleDbType.Raw;
parameter.Value = arrangedGuidList.ToArray();
例外:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'BulkInsertTempItemGuid'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
使用數組調用存儲過程一次(而不是調用接受原子項的過程並多次調用它)時,必須將OracleDbType設置為Array。 該值設置為結構化的基礎數據,如自定義oracle數據類型中所指定。 在這種情況下,它是一個byte [] []。
parameter.OracleDbType = OracleDbType.Array;
parameter.UdtTypeName = "GUIDARRAY";
parameter.Value = arrangedGuidList.ToArray();
// Note, do NOT set the collection type. Default it to "none"
然后我定義了我的Oracle自定義類型。 請看這里的例子。 我修改了SimpleVarray / SimpleVarrayFactory類,但讓它們與Byte [] []一起使用。
%ODAC_HOME%\ODACsamples\odp.net\4\UDT
工廠類的關鍵部分是自定義類型映射必須與參數的UdtTypeName屬性匹配,並且是全部大寫。 似乎OracleCustomTypeMapping導致ODAC在運行時將參數中指定的自定義類型綁定到參數,並通過ToCustomObject / FromCustomObject方法在引擎蓋下的某處構建GuidArray類。
[OracleCustomTypeMapping("GUIDARRAY")]
public class GuidArrayFactory : IOracleCustomTypeFactory, IOracleArrayTypeFactory
{
public IOracleCustomType CreateObject()
{
return new GuidArray();
}
// IOracleArrayTypeFactory Inteface
public Array CreateArray(int numElems)
{
return new Byte[numElems][];
}
public Array CreateStatusArray(int numElems)
{
// CreateStatusArray may return null if null status information
// is not required.
return new OracleUdtStatus[numElems];
}
}
-
// See %ODAC_HOME%\ODACsamples\odp.net\4\UDT
public class GuidArray : IOracleCustomType, INullable
{
[OracleArrayMapping]
public Byte[][] Array;
private OracleUdtStatus[] m_statusArray;
public OracleUdtStatus[] StatusArray
{
get
{
return m_statusArray;
}
set
{
m_statusArray = value;
}
}
private bool m_bIsNull;
public bool IsNull
{
get
{
return m_bIsNull;
}
}
public static GuidArray Null
{
get
{
GuidArray obj = new GuidArray();
obj.m_bIsNull = true;
return obj;
}
}
public void ToCustomObject(OracleConnection con, IntPtr pUdt)
{
object objectStatusArray = null;
Array = (Byte[][])OracleUdt.GetValue(con, pUdt, 0, out objectStatusArray);
m_statusArray = (OracleUdtStatus[])objectStatusArray;
}
public void FromCustomObject(OracleConnection con, IntPtr pUdt)
{
OracleUdt.SetValue(con, pUdt, 0, Array, m_statusArray);
}
public override string ToString()
{
if (m_bIsNull)
return "GuidArray.Null";
string rtnstr = String.Empty;
if (m_statusArray[0] == OracleUdtStatus.Null)
rtnstr = "NULL";
else
rtnstr = Array.GetValue(0).ToString();
for (int i = 1; i < m_statusArray.Length; i++)
{
if (m_statusArray[i] == OracleUdtStatus.Null)
rtnstr += "," + "NULL";
else
rtnstr += "," + Array.GetValue(i);
}
return "GuidArray(" + rtnstr + ")";
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.