ODP ArrayBindSize
My Oracle Package Procedure signature is
PROCEDURE Get_Object_Details(
p_ObjectID IN VARCHAR2,
p_FullLoad IN VARCHAR2,
p_PropName OUT gt_PropNames,
p_PropValue OUT gt_PropValues,
gt_PropNames,gt_PropValues etc. are of type table and definition is as follows.
TYPE gt_PropNames IS TABLE OF VARCHAR2(50)INDEX BY BINARY_INTEGER;
I want to execute the Procdure from my .NET application using ODP.
Sample Code which i am using is :
string strConnString = "User Id=xyz;Password=xyz;Data
Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = Abc)(PORT = 1521)))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = EX_SID)));";
OracleParameter param_ObjectID = new
OracleParameter("p_ObjectID",OracleDbType.Int32);
param_ObjectID.Direction = ParameterDirection.Input;
param_ObjectID.Value = Convert.ToInt32(6);
OracleParameter strFullLoad = new
OracleParameter("p_FullLoad",OracleDbType.Varchar2);
strFullLoad.Direction = ParameterDirection.Input;
strFullLoad.Value = "T";
OracleParameter p_PropName = new
OracleParameter("p_PropName",OracleDbType.Varchar2);
p_PropName.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
p_PropName.Direction = ParameterDirection.Output;
p_PropName.Size = 1000;
OracleParameter p_PropValue = new OracleParameter("p_PropValue",
OracleDbType.Varchar2);
p_PropValue.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
p_PropValue.Direction = ParameterDirection.Output;
p_PropValue.Size = 1000;
OracleParameter[] param =
{param_ObjectID,strFullLoad,p_PropName,p_PropValue};
try
OracleHelper.ExecuteNonQuery(strConnString,CommandType.StoredProcedure,"PKG1.Procedure1",param);
catch(Exception ee)
MessageBox.Show(ee.Message.ToString());
But is giving any Error. The Error is OracleParameter.ArrayBindSize is invalid.
I don't want to Set this property at design time. Because.. it is dynamic.
Please Post same sample code.
I am guessing you got this working already but here it is just in case somebody else could use it.
// allows one to build a variable sized array
private static OracleParameter BuildAssociativeArray(
string paramName
,OracleDbType paramType
,object[] values
,int bindSize
,ParameterDirection paramDirection
,bool skipNullItems)
int paramSize = 0;
object[] paramValues;
// set the parameter size and load up the parameter values and bind size
if (!skipNullItems)
paramSize = values.Length;
else
for (int i = 0; i < values.Length; i++)
if (values[i] != null)
paramSize++;
else
break; // stop at first null
paramValues = new object[paramSize];
int[] bindArray = new int[paramSize];
for (int i = 0; i < paramSize; i++)
paramValues[i] = values;
bindArray[i] = bindSize;
// create the parm now
OracleParameter parm = new OracleParameter(
paramName
, paramType
, paramValues.Length == 0 ? (object)DBNull.Value : paramValues
, paramDirection);
parm.Size = paramSize;
parm.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
if (paramSize != 0)
parm.ArrayBindSize = bindArray;
else
return parm;
and here is a sample of it being called
parmValues = new string[ArrayLen];
for (int i = 0; i < parmValues.Length; i++)
if (contact.ShippingAddress[i] == null)
parmValues[i] = null;
else
parmValues[i] = contact.ShippingAddress[i].ZIP5;
parms.Add(BuildAssociativeArray("p_ship_zip_5_code"
, OracleDbType.Char
, parmValues
, 5
, ParameterDirection.Input
, false));
Regards,
Mike
Similar Messages
-
Hi everybody,
I have a problem on inserting a blank string into a NOT NULL VARCHAR2 field by using a parameter on Oracle Data Provider for .NET (Version 9.2.0.4.0). It is possible to insert any strings with non-blank characters using a parameter and it is possible to insert blank strings using SQLPlusWorksheet, so it must be a problem of using ODP.
It seems to me when using parameters, strings are trimmed in some way, therefore a blank string is handled like an empty string is handled like NULL.
However, we need to insert blank strings and we really want to use parameters because of the performance gain.
Does anybody know how to handle blank strings with parameters or is it impossible because of a bug?
Thanks,
Rainer
Additional Information:
* TABLE STRUCTURE *
CREATE TABLE GLOBALTYPE
GT_ID VARCHAR2 (36) NOT NULL,
GT_NR NUMBER (5, 0) NOT NULL,
GT_NOTE VARCHAR2 (255),
GT_CREA DATE,
GT_MOD DATE,
GT_OWNER VARCHAR2 (36),
GT_EXPORTDB VARCHAR2 (50) NOT NULL,
GT_EXPORTDATE DATE NOT NULL,
GT_IMPORTDB VARCHAR2 (50) NOT NULL,
GT_IMPORTDATE DATE NOT NULL,
GT_NAME VARCHAR2 (40) NOT NULL
* COMMAND BEING EXECUTED *
{Oracle.DataAccess.Client.OracleCommand}
[Oracle.DataAccess.Client.OracleCommand]: {Oracle.DataAccess.Client.OracleCommand}
CommandText: "INSERT INTO GlobalType (GT_ID, GT_NR, GT_NOTE, GT_CREA, GT_MOD, GT_OWNER, GT_EXPORTDB, GT_EXPORTDATE, GT_IMPORTDB, GT_IMPORTDATE, GT_NAME) VALUES (:GT_ID, :GT_NR, :GT_NOTE, :GT_CREA, :GT_MOD, :GT_OWNER, :GT_EXPORTDB, :GT_EXPORTDATE, :GT_IMPORTDB, :GT_IMPORTDATE, :GT_NAME)"
CommandTimeout: 0
CommandType: Text
Connection: {Oracle.DataAccess.Client.OracleConnection}
Parameters: {Oracle.DataAccess.Client.OracleParameterCollection}
Transaction: {Oracle.DataAccess.Client.OracleTransaction}
UpdatedRowSource: Both
* PARAMETER HAVING BLANK STRING *
{Oracle.DataAccess.Client.OracleParameter}
ArrayBindSize: Nothing
ArrayBindStatus: Nothing
CollectionType: None
DbType: String
Direction: Input
IsNullable: False
Offset: 0
OracleDbType: Varchar2
ParameterName: ":GT_EXPORTDB"
Precision: 0
Scale: 0
Size: 1
SourceColumn: ""
SourceVersion: Current
Status: Success
Value: " " {String}
* EXCEPTION WHEN RUNNING ExecuteNonQuery ON COMMAND
{Oracle.DataAccess.Client.OracleException}
[Oracle.DataAccess.Client.OracleException]: {Oracle.DataAccess.Client.OracleException}
HelpLink: Nothing
InnerException: Nothing
Message: "ORA-01400: Einfügen von NULL in ("TEST"."GLOBALTYPE"."GT_EXPORTDB") nicht möglich"
Source: "Oracle Data Provider for .NET"
StackTrace: " at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()I have same problem.
I have 10.2 provider installed and I need to insert string.Empty in "VARCHAR2(200) NOT NULL" column:
Here is the code:
using (OracleConnection connection = GrinderHlp.OpenConnection(ConnectionString))
using (OracleCommand command = connection.CreateCommand())
command.CommandText = @"INSERT INTO dz_hist_data (par_value, time_stamp, quality, updated_when, g_time_stamp, obj_id, par_id, stat_aggr)
VALUES (:Value, :Time, :Quality, CURRENT_TIMESTAMP, :GTime, :ObjId, :ParId, :AggId)";
OracleParameter p1 = command.Parameters.Add("Value", OracleDbType.Varchar2, 50, ParameterDirection.Input);
OracleParameter p2 = command.Parameters.Add("Time", OracleDbType.Date, ParameterDirection.Input);
OracleParameter p3 = command.Parameters.Add("Quality", OracleDbType.Int16, ParameterDirection.Input);
OracleParameter p6 = command.Parameters.Add("GTime", OracleDbType.Date, ParameterDirection.Input);
OracleParameter p0 = command.Parameters.Add("ObjId", OracleDbType.Int32, ParameterDirection.Input);
OracleParameter p4 = command.Parameters.Add("ParId", OracleDbType.Int32, ParameterDirection.Input);
OracleParameter p5 = command.Parameters.Add("AggId", OracleDbType.Int32, ParameterDirection.Input);
p0.Value = 15004;
p1.Value = "";
p2.Value = DateTime.Now;
p3.Value = 192;
p4.Value = 1974;
p5.Value = 3;
p6.Value = DateTime.UtcNow;
command.ExecuteNonQuery();
The code fails with ORA-01400.
I tried to use OracleDbType.Char, .NChar and NVarchar2 instead of OracleDbType.Varchar2 and result was the same.
Here is the table structure:
CREATE TABLE dz_hist_data
(obj_id NUMBER(16,0) NOT NULL,
par_value VARCHAR2(200) NOT NULL,
time_stamp DATE NOT NULL,
quality NUMBER(3,0),
updated_when DATE NOT NULL,
par_id NUMBER(16,0) NOT NULL,
stat_aggr NUMBER NOT NULL,
diff_value NUMBER,
diff_ts DATE,
new_data CHAR(1) DEFAULT '1',
param_cond_id NUMBER,
g_time_stamp DATE
Can you help me? -
Hi,
I have the below Oracle procedure with two parameters , the first one i IS TABLE OF number INDEX BY BINARY_INTEGER, and the second one is of type Ref cursor of predifned RECORD type.
PROCEDURE Proc1(p_proj_comp_no_list IN core_util.ref_t,
p_proj_comp_post_query_cursor OUT t_proj_comp_post_query_cursor
) IS
This has been working fine while we were using DEVART Oracle drivers. however, as soon we move to ODP 11.2.0.1.1 Beta version we get the below error while executing the procedure via ODP.
{"ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'PROJ_COMP_POST_QUERY'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"}
Below is the debug watch result of the two parameters of the COMMAND being executed.
Best Regards,
Prabhakar
+ *base {P_PROJ_COMP_NO_LIST} System.Data.Common.DbParameter {Oracle.DataAccess.Client.OracleParameter}*
ArrayBindSize null int[]
ArrayBindStatus null Oracle.DataAccess.Client.OracleParameterStatus[]
CollectionType None Oracle.DataAccess.Client.OracleCollectionType
DbType String System.Data.DbType
Direction Input System.Data.ParameterDirection
IsNullable false bool
Offset 0 int
OracleDbType Long Oracle.DataAccess.Client.OracleDbType
OracleDbTypeEx Long Oracle.DataAccess.Client.OracleDbType
ParameterName "P_PROJ_COMP_NO_LIST" string
Precision 0 byte
Scale 0 byte
Size 1 int
SourceColumn "" string
SourceColumnNullMapping false bool
SourceVersion Current System.Data.DataRowVersion
Status Success Oracle.DataAccess.Client.OracleParameterStatus
UdtTypeName "" string
+ Value {long[1]} object {long[]}
+ Static members
+ Non-Public members
- [1] {P_PROJ_COMP_POST_QUERY_CURSOR} object {Oracle.DataAccess.Client.OracleParameter}
+ *base {P_PROJ_COMP_POST_QUERY_CURSOR} System.Data.Common.DbParameter {Oracle.DataAccess.Client.OracleParameter}*
ArrayBindSize null int[]
ArrayBindStatus null Oracle.DataAccess.Client.OracleParameterStatus[]
CollectionType None Oracle.DataAccess.Client.OracleCollectionType
DbType Object System.Data.DbType
Direction Output System.Data.ParameterDirection
IsNullable false bool
Offset 0 int
OracleDbType RefCursor Oracle.DataAccess.Client.OracleDbType
OracleDbTypeEx RefCursor Oracle.DataAccess.Client.OracleDbType
ParameterName "P_PROJ_COMP_POST_QUERY_CURSOR" string
Precision 0 byte
Scale 0 byte
Size 0 int
SourceColumn "" string
SourceColumnNullMapping false bool
SourceVersion Current System.Data.DataRowVersion
Status Success Oracle.DataAccess.Client.OracleParameterStatus
UdtTypeName "" string
+ Value {} object {System.DBNull}
+ Static members
+ Non-Public membersHi,
Can you please show the actual code that creates and appends the parameters instead, along with cmd.commandtext?
Thanks
Greg
Edited by: gdarling on Jun 30, 2010 11:54 AM
Also note that unless you're using Oracle Developer Tools for VS to generate the code, this would probably be more appropriate in the ODP forum:
ODP.NET -
ArrayBindSize and Size for PLSQLAssociativeArrays
Hey there,
I'm a complete newbie to ODP.NET and was hoping someone may be able to help with an issue. I basically need to call an SP from a VB.NET application and got as far as I could with the code below. The problem is that the parameters associates to this SP are all direction output. As a result, i'm having trouble trying to use the ArrayBindSize property and the Size property since I don't know what the number/size of the output from running the SP will exactly be? Does anyone see my predicament?
I'm also seeing the following errors when I try to compile my application:
Value of type '1-dimensional array of String' cannot be converted to '1-dimensional array of Integer' because 'String' is not derived from 'Integer'.
Thanks in advance!
Public Function RunSPReturnDS()
Try
Dim oraConnString As String = "Data Source=*****;User Id=******;Password=*****;"
Dim oraConnection As New OracleConnection(oraConnString)
oraConnection.Open()
MessageBox.Show("Connection works!", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
oracleCMD = oraConnection.CreateCommand
oracleCMD.CommandType = CommandType.StoredProcedure
oracleCMD.CommandText = "OCDI_UTILITIES.GET_EXISS_TODAY"
pStatus = New OracleParameter("P_STATUS", OracleDbType.Int32)
pStatusText = New OracleParameter("P_STATUS_TEXT", OracleDbType.Varchar2)
pRecReturned = New OracleParameter("P_RECORDS_RETURNED", OracleDbType.Int32)
pMsgSysNameList = New OracleParameter("P_MSG_SYSTEM_NAME_LIST", OracleDbType.Varchar2)
pMsgLastInDateTime = New OracleParameter("P_MSG_LAST_IN_DATETIME_LIST", OracleDbType.Date)
pMsgGoodIn = New OracleParameter("P_MSG_GOOD_IN_LIST", OracleDbType.Int32)
pMsgBadIn = New OracleParameter("P_MSG_BAD_IN_LIST", OracleDbType.Int32)
pMsgLastOutDateTime = New OracleParameter("P_MSG_LAST_OUT_DATETIME_LIST", OracleDbType.Date)
pMsgGoodOut = New OracleParameter("P_MSG_GOOD_OUT_LIST", OracleDbType.Int32)
pMsgBadOut = New OracleParameter("P_MSG_BAD_OUT_LIST", OracleDbType.Int32)
pStatus.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pStatusText.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pRecReturned.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgSysNameList.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgLastInDateTime.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgGoodIn.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgBadIn.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgLastOutDateTime.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgGoodOut.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pMsgBadOut.CollectionType = OracleCollectionType.PLSQLAssociativeArray
pStatus.Direction = ParameterDirection.Output
pStatusText.Direction = ParameterDirection.Output
pRecReturned.Direction = ParameterDirection.Output
pMsgSysNameList.Direction = ParameterDirection.Output
pMsgLastInDateTime.Direction = ParameterDirection.Output
pMsgGoodIn.Direction = ParameterDirection.Output
pMsgBadIn.Direction = ParameterDirection.Output
pMsgLastOutDateTime.Direction = ParameterDirection.Output
pMsgGoodOut.Direction = ParameterDirection.Output
pMsgBadOut.Direction = ParameterDirection.Output
pStatus.Size = 10
pStatusText.Size = 10
pRecReturned.Size = 10
pMsgSysNameList.Size = 10
pMsgLastInDateTime.Size = 10
pMsgGoodIn.Size = 10
pMsgBadIn.Size = 10
pMsgLastOutDateTime.Size = 10
pMsgGoodOut.Size = 10
pMsgBadOut.Size = 10
'pStatus.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pStatusText.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pRecReturned.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgSysNameList.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgLastInDateTime.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgGoodIn.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgBadIn.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgLastOutDateTime.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgGoodOut.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
'pMsgBadOut.ArrayBindSize = New Int32(10) {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100}
pStatus.ArrayBindSize = BindArraysToSizeInt()
pStatusText.ArrayBindSize = BindArraysToSizeStr()
pRecReturned.ArrayBindSize = BindArraysToSizeInt()
pMsgSysNameList.ArrayBindSize = BindArraysToSizeStr()
pMsgLastInDateTime.ArrayBindSize =
pMsgGoodIn.ArrayBindSize = BindArraysToSizeInt()
pMsgBadIn.ArrayBindSize = BindArraysToSizeInt()
pMsgLastOutDateTime.ArrayBindSize =
pMsgGoodOut.ArrayBindSize = BindArraysToSizeInt()
pMsgBadOut.ArrayBindSize = BindArraysToSizeInt()
oracleCMD.Parameters.Add(pStatus)
oracleCMD.Parameters.Add(pStatusText)
oracleCMD.Parameters.Add(pRecReturned)
oracleCMD.Parameters.Add(pMsgSysNameList)
oracleCMD.Parameters.Add(pMsgLastInDateTime)
oracleCMD.Parameters.Add(pMsgGoodIn)
oracleCMD.Parameters.Add(pMsgBadIn)
oracleCMD.Parameters.Add(pMsgLastOutDateTime)
oracleCMD.Parameters.Add(pMsgGoodOut)
oracleCMD.Parameters.Add(pMsgBadOut)
oracleCMD.ExecuteNonQuery()
For i As Integer = 0 To pStatus.Size - 1
Console.WriteLine(pStatus.Value(i))
Next
'ListView1.Items(3).SubItems.Add(P_STATUS)
pStatus.Dispose()
pStatusText.Dispose()
pRecReturned.Dispose()
pMsgSysNameList.Dispose()
pMsgLastInDateTime.Dispose()
pMsgGoodIn.Dispose()
pMsgBadIn.Dispose()
pMsgLastOutDateTime.Dispose()
pMsgGoodOut.Dispose()
pMsgBadOut.Dispose()
oracleCMD.Dispose()
oraConnection.Dispose()
Catch ex As Exception
MessageBox.Show(ex.Message.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Function
Private Function BindArraysToSizeInt() As Integer()
Dim ArrBindSizeInt(collectionObjectsInt.Count - 1) As Integer
For i As Integer = 0 To collectionObjectsInt.Count - 1
ArrBindSizeInt(i) = collectionObjectsInt(i).ToString().Length
Next i
Return ArrBindSizeInt
End Function
Private Function BindArraysToSizeStr() As String()
Dim ArrBindSizeStr(collectionObjectsStr.Count - 1) As String
For i As Integer = 0 To collectionObjectsStr.Count - 1
ArrBindSizeStr(i) = collectionObjectsStr(i).ToString().Length
Next i
Return ArrBindSizeStr
End Function
End ClassWell - yes and no :-)
When it comes to desktop displays then historically the term resolution has been used to describe only the Pixel Dimensions of the physical display and not the pixels per unit of measurement. Typically we don't bother any more about the screen PPI because its usually high enough not to be a problem.
Projectors on the other hand display the image on varying screen sizes due to the distance from the screen. This makes resolution in terms of PPI important again. Yes, the projector has 'fixed' pixel dimensions but because the screen size varies the PPI will also vary. The further away the screen gets the larger the Pixels get and at some distance the image gets very 'pixellated' i.e you start to see the actual pixels.
The other thing to keep in mind is that projectors are typically driven from a PC ( I guess we should include the Mac folks in this :-) )which may have a resolution (pixel dimensions) much higher than the projector. This may mean that you have to change the display properties on your PC to match or you may be lucky that the projector can re-sample for you.
To answer the OP then the resolution in terms of PPI is more a question of controlling the distance between projector and screen and you need to check this visually although the venue may limit what you can actually do.
In terms of Image Size (Pixel Dimensions) then I would say it depends on how critical you and your audience are, but to be honest there are probably other factors like colour, brightness and contrast that are going to be bigger issues than image sharpness.
Colin #2 -
PLSQLAssociativeArray - ArraybindSize
Hello all,
Does anybody know the maximum size of an output parameter for ArrayBindSize when accessing a table of varchar2. And if so is their a way to set the limit?
Right now I can go to a maximium of 2000 characters.
thanks,
DhavalActually odp.net limits us:
"ArrayBindSize is used only for parameter types that have variable length such as Clob, Blob and Varchar2. The size is represented in bytes for binary datatypes and characters for the Unicode string types. The count for string types does not include the terminating character. The size is inferred from the actual size of the value, if it is not explicitly set. For an output parameter, the size of each value is set by ODP.NET. The ArrayBindSize property is ignored for fixed length datatypes. "
But the doc doesn't state what size and whether if we can change the size or not. I know Microsoft's driver supports 4000 bytes (so I don't know why oracle would lessen the # of bytes returned). -
OracleParameter.ArrayBindSize is invalid
Hi,
Getting "OracleParameter.ArrayBindSize is invalid" error while using 'ArrayBindCount' method.
We are getting this error while using VARCHAR2 as an OUT parameter in the stored procedure.
'ArrayBindCount' works when we return NUMBER as an OUT parameter.
Stored Procedure Implementation
CREATE OR REPLACE PACKAGE SP_TEST_PA AS
PROCEDURE SP_TEST_PR(i_str_flg IN VARCHAR2,
o_str_err_code OUT VARCHAR2,
o_num_status OUT NUMBER) ;
END SP_TEST_PA;
CREATE OR REPLACE PACKAGE BODY SP_TEST_PA AS
PROCEDURE SP_TEST_PR(i_str_flg IN VARCHAR2,
o_str_err_code OUT VARCHAR2,
o_num_status OUT NUMBER) AS
BEGIN
o_str_err_code := 'SUCCESS';
o_num_status := 0;
EXCEPTION
WHEN OTHERS THEN
o_str_err_code := 'ERROR';
o_num_status := 1;
END SP_TEST_PR;
END SP_TEST_PA ;
VB.NET Code Implementation
Imports Oracle.DataAccess.Client
Dim lOCon As OracleConnection
Dim lOCmd As OracleCommand
Dim lOPRFlag As New OracleParameter("i_str_flg", OracleDbType.Varchar2, ParameterDirection.Input)
Dim lOPRErrorCode As New OracleParameter("o_str_err_code", OracleDbType.Varchar2, ParameterDirection.Output)
Dim lOPRStatus As New OracleParameter("o_num_status", OracleDbType.Decimal, ParameterDirection.Output)
Dim lIntArrayCount As Integer
Dim lArrFlag() As String = New String() {"N"}
Dim lArrErrCode() As String = New String() {"Y"} ' Default Value
Dim lArrStatus() As Integer = New Integer() {0} ' Default Value
Dim lStrProcedureName As String = "SP_TEST_PA.SP_TEST_PR"
Try
' Assign the values to the parameter
lOPRFlag.Value = lArrFlag
lOPRErrorCode.Value = lArrErrCode
lOPRStatus.Value = lArrStatus
' Set the ArrayCount for command to max. number of rows in the preceding arrays
lIntArrayCount = lArrStatus.Length
lOCon = New OracleConnection(CommonFunctionality.GetDBConnectionString)
lOCon.Open()
lOCmd = New OracleCommand(lStrProcedureName, lOCon)
lOCmd.CommandType = CommandType.StoredProcedure
' Bind the Length
lOCmd.ArrayBindCount = lIntArrayCount
lOCmd.Parameters.Add(lOPRFlag)
lOCmd.Parameters.Add(lOPRErrorCode)
lOCmd.Parameters.Add(lOPRStatus)
lOCmd.ExecuteNonQuery()
Catch ex As Exception
Finally
' Clean-up Activities
If Not (lOCmd Is Nothing) Then
lOCmd.Connection.Close()
lOCmd.Dispose()
End If
lOCmd = Nothing
If Not (lOCon Is Nothing) Then
If lOCon.State <> ConnectionState.Closed Then
lOCon.Close()
End If
lOCon.Dispose()
End If
lOCon = Nothing
End Try
Pl. help us.
Thanks & Regards,
Aditya from IndiaIt does not look like you've set the ArrayBindSize property as required:
"For binding a PL/SQL Associative Array, whose elements are of a variable-length element type, as an InputOutput , Out, or ReturnValue parameter, this property must be set properly."
- Oracle Data Provider for .NET Library, OracleParameter.ArrayBindSize
If you go to the ODP.NET home page and scroll to the bottom, you can get a sample download of 2 chapters from Pro .NET Oracle Programming (as of 16 JUN 2005). The ODP.NET home page can be found here:
http://www.oracle.com/technology/tech/windows/odpnet/index.html
Chapter 5 (which is part of the sample chapters) discusses working with PL/SQL and PLSQLAssociativeArray.
- Mark -
'ArrayBindSize is invalid' calling DBMS_DESCRIBE.DESCRIBE_PROCEDURE
I'm trying to call DBMS_DESCRIBE.DESCRIBE_PROCEDURE to get a listing of all of the parameters for a stored procedure. I'm having trouble getting the parameters created properly. Most of the params are declared as one of the following:
overload OUT NUMBER_TABLE,
argument_name OUT VARCHAR2_TABLE,
I've been using the following code (overload, for example):
m_Command.Parameters.Add("overload", OracleDbType.Double, 200, DBNull.Value, ParameterDirection.Output);
m_Command.Parameters[n].CollectionType = OracleCollectionType.PLSQLAssociativeArray;
m_Command.Parameters[n].ArrayBindSize = ???;
I've tried setting ArrayBindSize to several different values, but I always seem to get the following error message "OracleParameter.ArrayBindSize is invalid".
Thoughts?
Also, in ADO, you used to be able to call Command.Refresh, which would populate the Parameters object for you (slow as it may have been). Is there anything similar available for ODP?
Any help would be greatly appreciated.The DBMS_DESCRIBE.DESCRIBE_PROCEDURE contains Nested Table type parameters. Since ODP.NET does not support Nested Table type, it is not possible to execute the DBMS_DESCRIBE.DESCRIBE_PROCEDURE at this time. The Nested Table, VArray, Object supports will be evaluated in the near future.
Thanks
Martha -
ArrayBindSize-implicit (-1) length not valid for this bind or define dataty
Hello all,
This has been troubling me for a couple of days.
I am retriving an oracle type of varchar2 table:
TYPE VARCHAR2_TABLE IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;
I create the following array:
'size of the array
Dim intValue(4000) As Integer
Dim idx As Integer = 0
While idx < intValue.Length
'assingning 4000 tells that each row size
'will be of 4000 characters
intValue(idx) = 4000
idx = idx + 1
End While
Then I assign it to the parameter:
Dim param As OracleParameter = cmd.Parameters.Add("sBuffer", OracleDbType.Varchar2)
param.Direction = ParameterDirection.Output
param.Size = intValue.Length
param.CollectionType = OracleCollectionType.PLSQLAssociativeArray
param.ArrayBindSize = intValue
when I execute the query I get the error:
implicit (-1) length not valid for this bind or define datatype
However, if i assign each row the size of 2000 or less it returns fine. But this limits me to getting only 2000 characters. And our current system returns 4000 characters.
If any one has a solution, please post it.
thanks,
DhavalOk I've now found the patchsets and have ODP.NET 9.2.0.420 up and running - which is a start!
The 2000 character limit as discussed above does indeed seem to have gone - great! BUT: I'm now running into another limit:
It seems as though ODP.NEt and/or the layers below reserve 3 bytes of memory for every character when binding a PLSQLAssociativeArray OUTPUT parameter. Due to what looks like the old 16Mb-per-array limit I used to encounter when using Microsoft OLEDB Provider for Oracle, this means that, for an array of VARCHAR2(4000), the maximum number of rows (array elements) I can get back is 1398, before I get an exception with the message:
"ORA-01044: size 16788000 of buffer bound to variable exceeds maximum 16777216 occured"
When using the Microsoft OLEDB Provider there seems to be a 1-byte-per-character sizing going on, since I can get up to 4194 rows (array elements) back from the same stored procedure.
Any reasoning behind the 3-bytes per character with ODP.NET? -
ODP and ADO and a trigger - problem
I have written a simple trigger to turn on tracing for a session based on the username:
It works fine through sqlplus. The application works when run using JDBC and native(?) java. But when we use hibernate and ODP.net and ADO.net The session goes into a loop of recursive sql and gets an ORA-36 too many recursive levels. I am not a java developer and I am at a loss on how to proceed. It appears to be firing the trigger or have fired the trigger, and then look for global_db_name until it dies.
CREATE OR REPLACE TRIGGER gopal_user_login_trigger
AFTER LOGON ON DATABASE
DECLARE
user_name VARCHAR2(30);
BEGIN
SELECT username INTO user_name FROM sys.V$SESSION
WHERE audsid = USERENV('SESSIONID') AND audsid != 0 ;
IF UPPER(user_name) = 'GOPALASSETUSER'
THEN
DBMS_MONITOR.SESSION_TRACE_ENABLE(NULL, NULL, true, true);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND then null;
END;Hi,
Thanks for the bug number - that helped alot.
Why the global_db_name lookup, I do not know. It appears to be part of the logon processing that follows the trigger.It is, indeed, part of the logon process and is called by internal code so that makes sense now.
If you have MetaLink support, I would recommend opening an SR. One simple thing that I might suggest is to set "enlist=false" in your connect string if you can and test with that.
Thanks,
Mark -
Performance problems with Integrated security and ODP
Hi
While testing performance for opening a data base connection, I notice there is a huge performace issue when using externally identified users and ODP with Oracle client 11.1.0.6 and .Net 3.5. The test is running 30 times slower with an externally identified user compared to using a database identified user.
I also noticed that System.Data.OracleClient does not result in any significant performance penalties for externally vs database identified users.
The test environment is Vista 64 and VS2008, and I do not notice any significant difference using 32bit vs 64bit Oracle client.
Is this a known problem and does it exist a workaround for this?
Kind regards
OyvindHi,
I'm assuming you're using 11.1.6.0 ODP, so you'd want to upgrade to 11.1.6.21 or higher ODP. Prior to that, Externally Authenticated connections were not pooled so resulted in a hard connection every time.
If you have 111060 full client installed, applying the 11107 database patch to the cleint install will give you 11107 ODP. Or, you can add the [11106.20 ODAC bundle|http://www.oracle.com/technology/software/tech/windows/odpnet/index.html] into your existing 111060 full client home as well.
Hope it helps,
Greg -
Global temp table problem w/ODP?
I'm using the current version of the ODP .NET data adapter to access a global temporary table on an Oracle
9.2.0.4.0 server created with -
CREATE GLOBAL TEMPORARY TABLE euik_dex_open_tasks_temp1
(resource_id NUMBER,
task_assignment_id NUMBER,
task_id NUMBER,
incident_id NUMBER,
customer_product_id NUMBER,
inventory_item_id NUMBER,
contract_service_id NUMBER)
ON COMMIT DELETE ROWS
(See below for what is returned from the data dictionary for this table)
If I use SQLPlus to insert a row into this table, then query the table immediately, I see the inserted row.
If I use the same exact SQL through the ODP adapter, the ExecuteNonQuery statement returns the fact the 1 row was inserted. However, doing a SELECT from the table immediately after the INSERT, no rows are returned. See the .NET test ap, below.
Also, note that if I use a global temp table made with ON COMMIT PRESERVE ROWS, the ODP adapter works fine.
What am I doing wrong? Thanks in advance...
Pat
Private Sub TestTempTable()
Dim Str1 As New System.Text.StringBuilder
Dim Strx As New System.Text.StringBuilder
Dim StrOut As New System.Text.StringBuilder
Dim nInsert As Integer
Dim nRow As Integer
'Insert into the global temp table
Str1.Append("INSERT INTO euik_dex_open_tasks_temp1(resource_id, " & vbCrLf)
Str1.Append(" task_Assignment_id, " & vbCrLf)
Str1.Append(" task_id, " & vbCrLf)
Str1.Append(" incident_id, " & vbCrLf)
Str1.Append(" customer_product_id, " & vbCrLf)
Str1.Append(" inventory_item_id, " & vbCrLf)
Str1.Append(" contract_service_id) " & vbCrLf)
Str1.Append(" VALUES(1,2,3,4,5,6,7)" & vbCrLf)
Dim cn As New Oracle.DataAccess.Client.OracleConnection
Dim dr As Oracle.DataAccess.Client.OracleDataReader
Dim cd As New Oracle.DataAccess.Client.OracleCommand
Try
cn.ConnectionString = "Data Source=XXX;User ID=mickey;Password=mouse;"
cd.CommandType = CommandType.Text
cd.Connection = cn
cn.Open()
'Run the query to load data in the temp table
cd.CommandText = Str1.ToString()
nInsert = cd.ExecuteNonQuery()
MessageBox.Show(nInsert & " row(s) inserted.")
'See if there are rows in the temp table
Strx.Append("Select * from euik_dex_open_tasks_temp1")
cd.CommandText = Strx.ToString()
dr = cd.ExecuteReader
nRow = 0
While dr.Read
StrOut.Append(dr(0) & vbCrLf)
nRow = nRow + 1
End While
MessageBox.Show(nRow & " row(s) selected.")
Catch ex As OracleClient.OracleException
MessageBox.Show(ex.Message)
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
cn.Close()
End Try
End Sub
OWNER TABLE_NAME TABLESPACE_NAME CLUSTER_NAME IOT_NAME PCT_FREE PCT_USED
INI_TRANS MAX_TRANS INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE
FREELISTS FREELIST_GROUPS LOGGING BACKED_UP NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE
CHAIN_CNT AVG_ROW_LEN AVG_SPACE_FREELIST_BLOCKS NUM_FREELIST_BLOCKS DEGREE INSTANCES
CACHE TABLE_LOCK SAMPLE_SIZE LAST_ANALYZED PARTITIONED IOT_TYPE TEMPORARY
SECONDARY NESTED BUFFER_POOL ROW_MOVEMENT GLOBAL_STATS USER_STATS DURATION
SKIP_CORRUPT MONITORING CLUSTER_OWNER DEPENDENCIES COMPRESSION
APPS EUIK_DEX_OPEN_TASKS_TEMP1 10 40 1 255
1 1 NO N
1 1 N ENABLED NO Y N NO
DEFAULT DISABLED NO NO SYS$TRANSACTION DISABLED NO DISABLED
DISABLEDAndrew,
As David indicated if you do not wish to have "auto commit mode" you just need to use a transaction object to manually control the transaction.
I'm just nervous at the idea of ODP.NET initiating interactions I am not aware of.I think it would be more fair to say "finishing interactions" in this case rather than "initiating interactions" but you could always just run a SQL trace from the database to see exactly what is happening if you are concerned.
HTH,
- Mark
=======================================
Mark A. Williams
Oracle DBA
Author, Professional .NET Oracle Programming
http://www.apress.com/book/bookDisplay.html?bID=378 -
Availability of DbProviderFactory in ODP
Does anyone know if Oracle or someone has created a DbProviderFactory for ODP. From the page
http://msdn.microsoft.com/en-us/library/cy5kfe3c(v=VS.80).aspx
ADO.NET 2.0 introduces new base classes in the System.Data.Common namespace. The base classes are abstract... They include DbConnection, DbCommand, and DbDataAdapter
The Factory Design Pattern
The programming model for writing provider-independent code is based on the use of the "factory" design pattern, which uses a single API to access databases across multiple providers. This pattern is aptly named, as it calls for the use of a specialized object solely to create other objects, much like a real-world factory.I may be missing the point here, but what are you looking for? ODP supports factory classes when support for ADO.NET 2.x was introduced in 10.2.0.2.21, and factory class code is generic.
If you click the "Writing Generic Data Access Code in ASP.NET 2.0 and ADO.NET 2.0" link in the URL you've referenced, you'll see sample code. To change that code to use ODP, simply change
DbProviderFactory provider = DbProviderFactories.GetFactory("System.Data.SqlClient");
to
DbProviderFactory provider = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
and provide an appropriate connect string.
Note however that you won't be able to take advantage of a lot of the functionality built into ODP without introducing ODP specific code, as the common framework is somewhat like ODBC in that it's written to the lowest common functionality.
Corrections/comments welcome, hope it helps.
Greg
DbProviderFactory provider = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
DbConnection con = provider.CreateConnection();
con.ConnectionString = @"Data Source=mytnsnamesalias; user id=myuid;password=mypwd";
DbCommand com = provider.CreateCommand();
com.Connection = con;
com.CommandText = "Select * From Subscribers";
com.CommandType = CommandType.Text;
DataSet ds = new DataSet();
DbDataAdapter ad = provider.CreateDataAdapter();
ad.SelectCommand = com;
con.Open();
ad.Fill(ds);
con.Close();
return ds.Tables[0].DefaultView;Edited by: gdarling on Jun 18, 2010 10:27 AM -
How to create SAP Extractor based ODP on Hana?
Hi SAP Gurus,
I am a HANA begginer and trying to create an SAP extractor based ODP.
Till now i have created a source system under "ODP - SAP (Extractors)" node of source system screen. I didn't enter any source system and type because there was no choice in the help list.
Connection test and authorization test through sm59 are working with no problem.
In the source system i activated datasource 0FI_GL_4 and made sure that's working through rsa3 . I can retrieve more than 1000 line of data. So everything seems alright but when i try to replicate data source in HANA system i got this error;
"Destination DTYIDS_IDS_00: ping waiting time (5 seconds) exceeded
Message no. RSDS571"
Some information on this issue and latter steps in order to create an ODP will be greatly appreciated.
Best regards,
YağızI got the solution.
CREATE OR REPLACE FUNCTION conv_str_to_date(c VARCHAR2) RETURN DATE
deterministic AS
BEGIN
RETURN(TO_DATE(c,'MM/DD/YY'));
END;
CREATE INDEX my_date_index ON XML_TEST
et (conv_str_to_date (et.xml_msg.extract('//DDate/text()').getStringVal())); -
Active ODP when both 9 and 10g are installed...
I have both ODP 9i and ODP 10g (along with the Oracle 10g client) installed on my workstation. How does one set up one or the other to be the 'active' ODP client? For instance, I have an application that I developed under ODP 9i... because I developed this under ODP 9, I want it to run under ODP 9 on my or anyone else's workstation. However, when I view it in the Visual Studio 2003 IDE, it shows ODP 10 as the 'active' client. Even when I run it, I find it is using ODP 10 (I know this because I have a Help...About screen in my runtime that displays the loaded assemblies) Even if I install it on a plain workstation (i.e. no Visual Studio 2003) with both 9i and 10g installed, and even though it was fully compiled using 9i, it still shows up as using the 10g ODP client. I don't want that at this time - if I compile it under 9i I want it to use Oracle 9i... Otherwise, what is the sense of having both clients on the machine?
So.... bottom line... is there a way to set one of the ODP clients to be 'active' even though both clients are installed?
Thanks in advance.
TomHi,
By default, ODP installs publisher policy files to redirect to the latest version of ODP, which would make an app compiled with 92x odp use the 10x odp instead. If you dont want that to happen, delete the oracle.dataaccess publisher policy files from the GAC, but then you'll get no redirection at all. IE, you'll have to have the exact version the app was compiled with on that box to run the app.
Or, as msolnit pointed you to above, there's an article on the MS site that explains more about it, and other ways to prevent it on a per-application basis (see the Bypassing Publisher Policy section of that article)
Cheers, hope it helps.
Greg -
How to define a output parameter in C# which maps to a PL/SQL table (odp)?
OracleConnection objconnection = new OracleConnection(connectionstring);
OracleCommand objcommand = objconnection.CreateCommand();
objcommand.Connection = objconnection;
objcommand.CommandText = "UBE_XSITE_PKG_V2.SP_DATAUPLOAD";
objcommand.CommandType = CommandType.StoredProcedure;
ListBox1.SelectedIndex = 0;
OracleParameter prm1 = new OracleParameter("PI_LOT", OracleDbType.Varchar2);
prm1.Direction = ParameterDirection.Input;
prm1.Value = ListBox1.SelectedValue.ToString();
objcommand.Parameters.Add(prm1);
OracleParameter prm2 = new OracleParameter("PI_WS_OP", OracleDbType.Int32);
prm2.Direction = ParameterDirection.Input;
prm2.Value = (float)Int32.Parse(TextBox3.Text);
objcommand.Parameters.Add(prm2);
OracleParameter prm3 = new OracleParameter("PI_SOURCE_SITE", OracleDbType.Varchar2);
prm3.Direction = ParameterDirection.Input;
prm3.Value = DropDownList1.SelectedValue.ToString();
objcommand.Parameters.Add(prm3);
OracleParameter prm4 = new OracleParameter("PI_WS_FLAG", OracleDbType.Varchar2);
prm4.Direction = ParameterDirection.Input;
prm4.Value = DropDownList5.SelectedValue.ToString();
objcommand.Parameters.Add(prm4);
OracleParameter prm5 = new OracleParameter("PI_WS_QTY", OracleDbType.Int32);
prm5.Direction = ParameterDirection.Input;
prm5.Value = (float)Int32.Parse(TextBox2.Text);
objcommand.Parameters.Add(prm5);
OracleParameter prm6 = new OracleParameter("PO_EXCEPTIONS", OracleDbType.Varchar2);
prm6.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
prm6.Direction = ParameterDirection.Output;
prm6.IsNullable = true;
prm6.Size = 4000;
objcommand.Parameters.Add(prm6);
objconnection.Open();
objcommand.ExecuteNonQuery();
objconnection.Close();Hi,
You'll need to provide more detail about what the plsql type is exactly.
However, you should check the ODP docs for examples, and it installs complete examples on your hard drive as well which will probably show you what you need to know.
As of 11.1.6.20, ODP.NET supports user defined types. Prior to that, it also supports Associative Arrays (Index-by tables).
Hope it helps
Greg
Maybe you are looking for
-
I have multiple ID Tags on My Page, How To Correct And Change To CLASS ID's
Hello Dreamweaver Word: I still have problems. On my website wwww.theexecutivevip.com My MENU BAR has moved down to the bottom of the page. On the various product pages [problem is seen in Internet Explorer Browser] I have multiple "main content" ID
-
Specific Row_ID's of a dataset, scattered on a page.
this seems like such an elementary question, but i just can't figure it out. i have an HTML dataset (ds1), which has several rows to it. and i have a spry region defined on my page (but not a repeating region). within that region, i want to specifica
-
Inter Company Stock Transfer Order
Hi, We have a requirment , where we will be transferring the stock between two companies. ie compnay code The companies belong to the same client. Can anyone give the process to be followed ie what is the firstr activity and so on. I had tried to g
-
I am trying to validate a text field so that it only accepts the month in numerical form with a leading zero if less than 10. The data type is Text Field, the value is "User Entered - Required" and the Validation pattern is 99. I have the following
-
Ive been buying adobe products online since photoshop cs2 and navigating the site has never been a problem. I wanted to buy indesign cs6, but mistakenly purchased the windows version. I own a mac. is there any way to fix this. I am unable to chat or