This answer to this question is fine, but I'm looking for ADO.NET code to be able to send an array or table to an Oracle procedure and then use that table in the procedure.
In SQL Server table-valued parameters, it's pretty straightforward:
CREATE TYPE [dbo].[IntTable] AS TABLE(
[intvalue] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[intvalue] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
CREATE PROCEDURE dbo.UseTable
@SomeInt INT
,@IntTable dbo.IntTable READONLY
AS
BEGIN
-- Do whatever using @SomeInt and @IntTable like:
INSERT INTO Assignments (masterid, childid)
SELECT @SomeInt, intvalue
FROM @IntTable
END
GO
Then on the client:
var param = new List<int>();
param.Add(1);
param.Add(2);
Cm.Parameters
.AddWithValue("@IntTable", param /* IEnumerable<Int> */)
.SqlDbType = SqlDbType.Structured
This is what I currently have:
CREATE OR REPLACE TYPE TRAIT_ID_TABLE AS TABLE OF NUMBER;
PROCEDURE SET_TRAITS(P_CUST_TANK_PROD_ID IN CUST_TANK_PROD.CUST_TANK_PROD_ID%TYPE, P_TRAIT_IDS IN TRAIT_ID_TABLE)
AS
BEGIN
DELETE FROM TANK_TRAIT
WHERE CUST_TANK_PROD_ID = P_CUST_TANK_PROD_ID;
INSERT INTO TANK_TRAIT(CUST_TANK_PROD_ID, TRAIT_ID)
SELECT P_CUST_TANK_PROD_ID, COLUMN_VALUE FROM TABLE(P_TRAIT_IDS);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
END;
var param = new OracleParameter();
param.ParameterName = "P_TRAIT_IDS";
param.OracleDbType = OracleDbType.Decimal;
param.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
param.Direction = ParameterDirection.Input;
param.Value = traitIdList.ToArray<int>();
param.Size = traitIdList.Count;
cmd.Parameters.Add(param);
And I get this on the ExecuteNonQuery:
System.AccessViolationException was caught
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=Oracle.DataAccess
StackTrace:
at Oracle.DataAccess.Client.OpsSql.ExecuteNonQuery(IntPtr opsConCtx, IntPtr& opsErrCtx, IntPtr& opsSqlCtx, IntPtr& opsDacCtx, IntPtr opsSubscrCtx, Int32& isSubscrRegistered, OpoSqlValCtx*& pOpoSqlValCtx, OpoSqlRefCtx& pOpoSqlRefCtx, IntPtr[] pOpoPrmValCtx, OpoPrmRefCtx[] pOpoPrmRefCtx, OpoMetValCtx*& pOpoMetValCtx, Int32 prmCnt)
at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
at EDC2.Domain.TraitList.SaveTraits(String connectionString) in C:\code\EDC2\trunk\app\EDC2.Domain\Trait.cs:line 195
InnerException: