How to Pass datatable as input to procedure in C#? - oracle

I am wrote stored procedure to Insert data into database table but i am not getting how to pass datatable to stored procedure kindly tell how to use it.
below is my storedprocedure
CREATE OR REPLACE PROCEDURE PR_SREE_TEST(p_recordset In SYS_REFCURSOR) IS
Contrac_rc SREE_TEST%rowtype;
BEGIN
Loop
Fetch p_recordset Into Contrac_rc;
EXIT WHEN p_recordset%NOTFOUND;
Insert into SREE_TEST(CT,DESC,FLAG)
Values(Contrac_rc.CT,Contrac_rc.DESC,Contrac_rc.FLAG);
End Loop;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
-- Consider logging the error and then re-raise
RAISE;
END PR_SREE_TEST;
/
and cs page
public DataSet sreetest(DataTable dt)
{
DataSet dsRegularIndentdtl = new DataSet();
try
{
OracleConnection OraConn = new OracleConnection(strDBConnection);
OraConn.Open();
OracleCommand OraCmd = new OracleCommand();
OraCmd.Connection = OraConn;
OraCmd.CommandText = "PR_SREE_TEST";
OraCmd.CommandType = CommandType.StoredProcedure;
OracleParameter parameter = new OracleParameter();
var recordSet1 = new DataTable();
recordSet1 = dt;
OraCmd.Parameters.Add("p_recordset", OracleDbType.RefCursor, recordSet1, ParameterDirection.Input);
OraCmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
return dsRegularIndentdtl;
}
}
above is my code it is saying that p_recordset not valied. please tell me how to execute it.

Make sure you are using the correct overload of OraCmd.Parameters.Add(),
As per msdn the fourth parameter is not parameter direction, it is as below
public OracleParameter Add(
string parameterName,
OracleType dataType,
int size,
string srcColumn
)

Related

Sys_Refcursor is null

I have this c# code
public static DataSet Get_Workflow_Def()
{
OracleConnection conn = DatabaseHelper.getOracleConnection();
DataSet dataset = new DataSet();
Log.Info("Opening connection");
conn.Open();
OracleCommand cmd = new OracleCommand("CTS.GET_WORKFLOW_DEF", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("p_Dataset", OracleDbType.RefCursor).Direction =
ParameterDirection.Output;
Log.Info("Executing query");
cmd.ExecuteNonQuery();
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.Fill(dataset);
conn.Close();
return dataset;
}
Calling this procedure
create or replace procedure CTS.GET_WORKFLOW_DEF(p_Dataset OUT
Sys_Refcursor)
as
begin
Open p_Dataset For
Select WKF_ID,
WKF_WORKFLOW_ID,
WKF_WORKFLOW_NAME,
WKF_WORKFLOW_VERSION,
WKF_WORKFLOW_SCHEMA
FROM CTS.WKF_WORKFLOW_MASTER
WHERE WKF_WORKFLOW_ACTIVE = '1'
ORDER BY WKF_ID DESC;
end GET_WORKFLOW_DEF;
If I execute the query I get the information I am looking for but the RefCursor is null. I'm an Oracle newb. Can anyone see where I am going wrong?
Found my problem I needed to add this line before the da.fill(dataset); line and after I instantiated the OracleDataAdapter in my c# code
da.TableMappings.Add("Table",
ConfigurationManager.AppSettings["DBPullTable"].ToString());

Wrong number or types of arguments when calling a procedure in WCF service

I'm sort of having a hard time with this one. Well ok, I have two different solutions (solution1 has a WebApplication Project; solution2 has a Website Project). Inside the two solutions, there's a WCF service structure. I have the exact same code in both services (in their respective solutions). My code compiles just fine. From the service I do a simple call to a procedure that returns a cursor. When I execute the service from the WebApplication it works just fine; when I do the same from the Website I get error: "wrong number or types of arguments". They both call the same procedure, in the same DB. And I triple check my code, and is the same in both services. Any ideas or suggestions? My code is as follows in both solutions:
Service.cs
public List<A1001310> SearchClient_A1001310()
{
DataTable dataTable = new DataTable();
dataTable = DataManager.SearchClient();
List<A1001310> list = new List<A1001310>();
list = (from DataRow dr in dataTable.Rows
select new A1001310()
{
Id = Convert.ToInt32(dr["CLIENT_ID"]),
//ClientName = dr["NOM_CLIENTE"].ToString()
}).ToList();
return list;
}
DataManager.cs
public static DataTable SearchClient()
{
try
{
using (OleDbCommand cmd = new OleDbCommand(packetName + ".select_A1001310"))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlManager sqlManager = new SqlManager();
return sqlManager.GetDataTable(cmd);
}
}
catch (Exception ex)
{
//TODO; Handle exception
}
return null;
}
The call to DataTable is:
public DataTable GetDataTable(OleDbCommand cmd)
{
using (DataSet ds = GetDataSet(cmd))
{
return ((ds != null && ds.Tables.Count > 0) ? ds.Tables[0] : null);
}
}
public DataSet GetDataSet(OleDbCommand cmd)
{
using (DataSet ds = new DataSet())
{
this.ConvertToNullBlankParameters(cmd);
using (OleDbConnection conn = new OleDbConnection(cmd.Connection == null ? _dbConnection : cmd.Connection.ConnectionString))
{
cmd.Connection = conn;
cmd.CommandTimeout = _connTimeout;
conn.Open();
//cmd.ExecuteScalar();
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
da.Fill(ds);
}
return ds;
}
}
The procedure is as follow:
PROCEDURE select_A1001310(io_cursor OUT lcursor_data)
AS
BEGIN
OPEN io_cursor FOR
--
SELECT client_id
FROM a1001310
WHERE status = 'A'
--
EXCEPTION
WHEN OTHERS THEN
IF io_cursor%ISOPEN THEN
CLOSE io_cursor;
END IF;
--REVIRE: EXCEPTION HANDLER
END select_A1001310;
So if it helps anyone, I resolved my issue by specifying the OUT parameter declared in the procedure. This resulted in me changing from Oledb to OracleClient as follow:
public static DataTable SearchClient()
{
string connection = ConfigurationManager.ConnectionStrings["DBConnection_Oracle"].ToString();
string procedure = packetName + ".p_search_client";
OracleParameter[] parameters = new OracleParameter[1];
parameters[0] = new OracleParameter("io_cursor", OracleType.Cursor, 4000, ParameterDirection.Output, true, 0, 0, "", DataRowVersion.Current, String.Empty);
DataTable dt = new DataTable();
dt = DataManager_Oracle.GetDataTable_(connection, procedure, parameters);
return dt;
}
It seems that on the Website environment it didn't like leaving out the OUT parameter; whereas on the WebApplication I did not specify it, and it worked just fine... If some one know the why , PLEASE let me know :)

How to use jmeter to test an Oracle Stored Procedure with sys_refcursor return type?

I want to test an Oracle Stored Procedure by using jmeter.I have done everything but parameters.
And here is my SQL Query:
declare
outinfo varchar2(20);
outtable sys_refcursor;
begin
{call RK_JSCX(?,?)};
end;
The outtable in Oracle is a cursor.And i used resultSet to contain it in java.However,whatever i set in parameter types ,it said invalid type.
Sample Start: 2012-10-25 16:06:41 CST
Load time: 0
Latency: 0
Size in bytes: 25
Headers size in bytes: 0
Body size in bytes: 25
Sample Count: 1
Error Count: 1
Response code: null 0
Response message: java.sql.SQLException: Invalid data type: cursor
Response headers:
oracle.jdbc.driver.T4CConnection#58ba09
SampleResult fields:
ContentType: text/plain
DataEncoding: UTF-8
How can fix it?
Thanks!
Here is my code in java:
public String RK_JSCX() throws Exception {
RK_JSCX_Response response = null;
List<RK_JSCX_Outtable> list = null;
Connection con = null;
CallableStatement cs = null;
ResultSet rs = null;
String sql = null;
try {
sql = "{call RK_JSCX(?,?)}";
con = ConnectionUtils.getInstance().getConnect();
if (con.isClosed()) {
throw new IllegalStateException("ERROR.THE CONNECTION ISCLOSED");
}
cs = con.prepareCall(sql);
cs.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
cs.registerOutParameter(2, Types.VARCHAR);
cs.execute();
rs = (ResultSet) cs.getObject(1);
list = new ArrayList<RK_JSCX_Outtable>();
while (rs.next()) {
RK_JSCX_Outtable out = new RK_JSCX_Outtable(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getInt(5), rs.getString(6));
list.add(out);
}
String outInfo = cs.getString(2);
response = new RK_JSCX_Response(list, outInfo);
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (rs != null) {
rs.close();
if (cs != null) {
cs.close();
}
if (con != null) {
con.close();
}
}
} catch (SQLException e) {
System.out.println("Exception2");
e.printStackTrace();
}
}
return JSON.toJSONString(response);
}
This is how to do it:
SQL Query : call RK_JSCX(?,?)
Parameter values : OUT, OUT
Parameter types : OUT -10,OUT VARCHAR
-10 being the int value of OracleTypes.CURSOR
Variable names: cursor, outInfo
Names are what you want
JMeter allows using more types than java.sql.Types constants, in this case instead of using Constant names, you use integer values of constants.
Documentation has been clarified (in next JMeter version) , see:
https://issues.apache.org/bugzilla/show_bug.cgi?id=54048
Try with the following changes
change the syntax in calling the procedure to
cs = con.prepareCall("BEGIN RK_JSCX(?, ?); END;");
And I believe your first OUT parameter is VARCHAR2 right? so
cs.registerOutParameter(1, Types.VARCHAR);
then
use the following to cast CallableStatement
rs = ((OracleCallableStatement)cs).getCursor(2);
Update 1
I have changed your procedure to demonstrate working version
Procedure
CREATE OR REPLACE PROCEDURE rk_jscx (outtable OUT sys_refcursor,
outinfo OUT VARCHAR2
)
AS
BEGIN
OPEN outtable FOR
SELECT SYSDATE
FROM DUAL;
outinfo := 1;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
outinfo := 2;
ROLLBACK;
END rk_jscx;
Java Code
CallableStatement stmt = conn.prepareCall("BEGIN rk_jscx(?, ?); END;");
stmt.registerOutParameter(1, OracleTypes.CURSOR);
stmt.registerOutParameter(2, Types.VARCHAR);
stmt.execute();
ResultSet rs = ((OracleCallableStatement)stmt).getCursor(1);
while (rs.next()) {
System.out.println(rs.getDate("sysdate"));
}
The above prints 2012-10-23
Check your jdbc driver as well

DbContext stored procedures oracle 11g

I am attempting to execute a stored procedure that has several in/out parameters. This is what the expected way of doing this with SQLServer would be.
using (Context)
{
const string xml = "<test><testc>testing</testc></test>";
var userIdParam = new SqlParameter { ParameterName = "I_USER_ID", Value = user.ID };
var dtsParam = new SqlParameter { ParameterName = "I_DTS", Value = DateTime.Now };
var timeoutParam = new SqlParameter { ParameterName = "I_TIMEOUT", Value = DateTime.Now };
var xmlParam = new SqlParameter { ParameterName = "I_XML", Value = xml };
var sessionIdParam = new SqlParameter { ParameterName = "O_SESSION_ID", Value = "", Direction = ParameterDirection.Output };
var result =
Context.Database.SqlQuery<string>(
"DALLEN.SP_INSERT_SESSION I_USER_ID, I_DTS, I_TIMEOUT, I_XML, O_SESSION_ID out",
userIdParam,
dtsParam,
timeoutParam,
xmlParam,
sessionIdParam);
}
Unfortunately this does not work with oracle. I understand that ref cursors might be used in place of out parameters but that is not my own issue. Is there a good way of passing parameters to the stored procedure using dbcontext.database.sqlquery?
EDIT
Error message received when the query attempts to execute. It explains that it doesn't accept sqlParamters so I changed them to OracleParamters and that didn't work either.
"Unable to cast object of type 'System.Data.SqlClient.SqlParameter' to type 'Oracle.DataAccess.Client.OracleParameter'."
Procedure:
CREATE OR REPLACE PROCEDURE DALLEN.SP_INSERT_SESSION (
I_USER_ID IN NUMBER,
I_DTS IN DATE,
I_TIMEOUT IN DATE,
I_XML IN VARCHAR2,
O_SESSION_ID OUT NUMBER
)
AS
BEGIN
SELECT S_SESSION.NEXTVAL
INTO O_SESSION_ID
FROM DUAL;
INSERT INTO DALLEN.SYS_SESSION
(ID, USER_ID, DTS, TIMEOUT, XML)
VALUES (O_SESSION_ID, I_USER_ID, I_DTS, I_TIMEOUT, I_XML);
END;
Thank you in advance!

Can not execute a sys_refcursor function without parameters

I have this sys_refcursor function in a package
function frcBaanCompanies return SYS_REFCURSOR is
x sys_refcursor;
begin
open x for select t$comp, t$cpnm from baan.tttaad100000 order by t$comp;
return x;
end;
and a net method calling this as so
listBox1.DataSource = lO.fRefCursor("priceWorx.frcBaanCompanies", null, false).Tables[0];
Here's how I call the function:
public DataSet fRefCursor(String refCursorName, IDictionary<string, string> prms, bool leaveConnectionOpen = true)
{
try
{
using (OracleCommand cmd = new OracleCommand("", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = refCursorName;
if (prms!=null) SetupParams(refCursorName, cmd, prms);
using (OracleDataAdapter da = new OracleDataAdapter(cmd))
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
cmd.Connection = conn;
}
using (DataSet ds = new DataSet())
{
da.Fill(ds);
return ds;
}
}
}
}
catch (Exception ex)
{
Debugger.Break();
Debug.WriteLine(ex);
return null;
}
finally
{
if (!leaveConnectionOpen) conn.Close();
}
}
The same method works fine when called with parameters(some other cursor function, but fails with
ORA-06550: line 1, column 7:
PLS-00221: 'FRCBAANCOMPANIES' is not a procedure or is undefined
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
works fine when executed within (Oracle) sql developer too..
What am I doing wrong ?
This is because you can't call a function without parameters, but you could call it with null parameters. What you are currently calling when you do not input any parameters is:
FRCBAANCOMPANIES;
and this is different to
variable := FRCBAANCOMPANIES;
In the first case oracle is looking for a procedure without any return and in the second case you call your function. So you have to set the return parameter also if you do not need it.

Resources