Error in executing Oracle Stored Procedure using C# - c#

I am trying to execute an Oracle stored procedure (1 input and 2 out parameters) using C#.
My table contain 3 columns; an integer id, and 2 varchar2 type columns.
This is table definition:
CREATE TABLE TESTTABLE
(
ID INT Not Null,
FNAME VARCHAR2(200),
LNAME VARCHAR2(200),
Constraint PK Primary Key (ID)
);
This is my stored procedure:
create or replace PROCEDURE TESTP
(
tempID IN TESTTABLE.ID%Type,
tempName Out TESTTABLE.NAME%TYPE,
tempLName out TESTTABLE.LNAME%TYPE
)
AS
BEGIN
select Name, LNAME
into tempName, tempLName
from TestTable
where ID = tempID;
END;
Here is the code to execute this procedure from C#:
try
{
Int32 id = 1;
string FName = "", LName = "";
using (_ora.GetOracleConnection())
{
Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand("TESTP", _ora.GetOracleConnection());
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("tempId", Oracle.DataAccess.Client.OracleDbType.Int32,ParameterDirection.Input).Value = id;
cmd.Parameters.Add("tempName", Oracle.DataAccess.Client.OracleDbType.Varchar2,200,ParameterDirection.Output).Value = FName;
cmd.Parameters.Add("tempLName", Oracle.DataAccess.Client.OracleDbType.Varchar2,200,ParameterDirection.Output).Value = LName;
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
This is the exception generated:
Oracle.DataAccess.Client.OracleException ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "USMANDBA.TESTP", line 9
Can anyone help me ?

These modifications in your code worked for me:
using (connection)
{
Int32 id = 1;
OracleCommand cmd = new OracleCommand("TESTP", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("tempID", OracleDbType.Int32, ParameterDirection.Input).Value = id;
cmd.Parameters.Add("tempName", OracleDbType.Varchar2, 200).Direction = ParameterDirection.Output;
cmd.Parameters.Add("tempLName", OracleDbType.Varchar2, 200).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
string FName = cmd.Parameters["tempName"].Value.ToString();
string LName = cmd.Parameters["tempLName"].Value.ToString();
}
You could also add exception blocks in Oracle procedure to handle no_data_found exception and avoid ORA-01403 error, like here:
CREATE OR REPLACE PROCEDURE TESTP (tempID IN TESTTABLE.ID%Type,
tempName out TESTTABLE.NAME%TYPE, tempLName out TESTTABLE.LNAME%TYPE) AS
BEGIN
select Name, LNAME Into tempName,tempLName from TestTable Where ID = tempID;
EXCEPTION WHEN NO_DATA_FOUND THEN
tempName := null;
tempLName := null;
END;
and add additional OUT parameter informing about success or failure and handle it in C# code.

Related

Get the primary key as output or return when you performing an Update query?

I'm trying to get the output parameter of primary key which is ID. When I do the update query I get Null. Can you please suggest a way to do this?
CREATE PROCEDURE sp_InsertTax
(#ID int output,
#TaxAuthorityID int,
#TaxClassificationID int,
#EntityID int,
#AppliesTo_TaxEntityTypeID int)
AS
IF EXISTS (SELECT * FROM Tax
WHERE TaxAuthorityID = #TaxAuthorityID
AND TaxClassificationID = #TaxClassificationID
AND EntityID = #EntityID
AND AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID)
BEGIN
UPDATE Tax
SET TaxAuthorityID = #TaxAuthorityID,
TaxClassificationID = #TaxClassificationID,
EntityID = #EntityID,
AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID
WHERE ID = #ID
END
ELSE
BEGIN
IF #ID IS NULL
BEGIN
INSERT INTO Tax(TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
VALUES (#TaxAuthorityID, #TaxClassificationID, #EntityID, #AppliesTo_TaxEntityTypeID)
SET #ID = Scope_Identity()
END
END
GO
The below is my ADO.NET code to call the update stored procedure:
public int InsertFederalTax(int ClassificID, int appliesTo)
{
int tax_id = 0;
Sqlconn.Open();
SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
cmd.CommandType = CommandType.StoredProcedure;
var returnparameter = cmd.Parameters.AddWithValue("ID", SqlDbType.Int);
returnparameter.Direction = ParameterDirection.Output;
cmd.Parameters.Add("#TaxAuthorityID", SqlDbType.Int).Value = 1;
cmd.Parameters.Add("#TaxClassificationID", SqlDbType.Int).Value = ClassificID;
cmd.Parameters.Add("#EntityID", SqlDbType.Int).Value = 0;
cmd.Parameters.Add("#AppliesTo_TaxEntityTypeID", SqlDbType.Int).Value = appliesTo;
cmd.ExecuteNonQuery();
if (!(returnparameter.Value is DBNull))
tax_id = Convert.ToInt32(returnparameter.Value);
Sqlconn.Close();
return tax_id;
}
I think you intended to capture the ID of an existing duplicate record, which you would do as follows. I've also added best practice template items for a SP. Also note the comment from marc_c about not prefixing your SP with sp_.
CREATE PROCEDURE InsertTax
(
#ID int output
, #TaxAuthorityID int
, #TaxClassificationID int
, #EntityID int
, #AppliesTo_TaxEntityTypeID int
)
AS
BEGIN
SET NOCOUNT, XACT_ABORT ON;
-- This assumes that none of the parameters can ever be null
-- And from your comments we know that no duplicates can exist
SELECT #ID = ID
FROM Tax
WHERE TaxAuthorityID = #TaxAuthorityID
AND TaxClassificationID = #TaxClassificationID
AND EntityID = #EntityID
AND AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID;
IF #ID IS NOT NULL BEGIN
UPDATE Tax
SET TaxAuthorityID = #TaxAuthorityID,
TaxClassificationID = #TaxClassificationID,
EntityID = #EntityID,
AppliesTo_TaxEntityTypeID = #AppliesTo_TaxEntityTypeID
WHERE ID = #ID;
END; ELSE BEGIN
INSERT INTO Tax (TaxAuthorityID, TaxClassificationID, EntityID, AppliesTo_TaxEntityTypeID)
VALUES (#TaxAuthorityID, #TaxClassificationID, #EntityID, #AppliesTo_TaxEntityTypeID);
SET #ID = SCOPE_IDENTITY();
END;
RETURN 0;
END;
GO
And I recommend declaring your return parameter as:
var returnparameter = new SqlParameter("#ID", SqlDbType.Int)
{
Direction = ParameterDirection.InputOutput
};
cmd.Parameters.Add(returnparameter);
Please, may you try to change your C# code with this updates bellow, and give us feed-back:
public int InsertFederalTax(int ClassificID, int appliesTo)
{
int tax_id = 0;
Sqlconn.Open();
SqlCommand cmd = new SqlCommand("sp_InsertTax", Sqlconn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#ID", SqlDbType.Int);
cmd.Parameters["#ID"].Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("#TaxAuthorityID", 1);
cmd.Parameters.AddWithValue("#TaxClassificationID", ClassificID);
cmd.Parameters.AddWithValue("#EntityID", 0);
cmd.Parameters.AddWithValue("#AppliesTo_TaxEntityTypeID", appliesTo);
cmd.ExecuteNonQuery();
if(!(cmd.Parameters["#ID"].Value is DBNull))
{
tax_id = Convert.ToInt32(cmd.Parameters["#ID"].Value);
}
Sqlconn.Close();
return tax_id;
}

How can I get the Last Index of mysql that has been inserted to C# code behind?

So I have a MySql stored procedure for inserting a row:
DELIMITER $$
CREATE PROCEDURE AddPosition(
IN strName VARCHAR(1000)
,IN strPositionType VARCHAR(1000)
,OUT intPositionId INT
)
BEGIN
INSERT INTO positions (
positionName
, positionType
)
VALUES(
strName
,strPositionType
);
SET intPositionId = LAST_INSERT_ID();
END
Honestly, I'm not really sure if this SET intPositionId = LAST_INSERT_ID(); works, I want to get the value of IntPositionId and bring it to C#
in my c#;
public bool AddItem(Position data)
{
int newId = 0;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "AddPosition";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("strName", data.PositionName).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("strPositionType", data.PositionType).Direction = ParameterDirection.Input;
cmd.Parameters.AddWithValue("intPositionId", SqlDbType.Int).Direction = ParameterDirection.Output;
try
{
MyHelper.MyExecuteNonQuery(cmd);
newId = (int) cmd.Parameters["intPositionId"].Value;
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
The newId = (int) cmd.Parameters["intPositionId"].Value; says "Specified cast is not valid."
when I tried to use debugging to find out what cmd.Parameters["intPositionId"].Value; returns,
it is just plain object with no value. I guess the SET intPositionId = LAST_INSERT_ID(); didnt work.
so where did I go wrong here?

Error in call from C# code-behind to a stored procedure: "PLS-00306: wrong number or types of arguments in call to"

I'm having this error when I call a stored procedure from my ASP.NET page's code-behind. I played with parameters and types but still couldn't figure out the reason.
Error:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'PR_SECWEB_GET_MAINTENANCE'
ORA-06550: line 1,
column 7: PL/SQL: Statement ignored
C# Code-behind method:
public static string GetMaintenanceFlag(string userType)
{
OracleConnection oConnection = new OracleConnection(connectionString);
OracleCommand oCommand = new OracleCommand();
string maintenanceFlag = string.Empty;
try
{
oCommand.CommandType = CommandType.StoredProcedure;
oConnection.Open();
oCommand.CommandText = GET_MAINTENANCE_FLAG;
oCommand.Parameters.Add("v_userType", OracleDbType.Varchar2);
oCommand.Parameters["v_userType"].Value = userType;
oCommand.Parameters.Add("cv_1", OracleDbType.Varchar2, 100);
oCommand.Parameters["cv_1"].Direction = ParameterDirection.Output;
oCommand.Connection = oConnection;
int cnt = oCommand.ExecuteNonQuery();
maintenanceFlag = oCommand.Parameters["cv_1"].Value.ToString();
return maintenanceFlag;
}
catch (Exception ex)
{
SecureWebExceptions oException = new SecureWebExceptions("CommonDAL", "GetMaintenanceFlag", ex);
throw oException;
}
finally
{
if (oConnection.State == ConnectionState.Open)
oConnection.Close();
}
}
Stored Procedure in Oracle:
create or replace PROCEDURE PR_SECWEB_GET_MAINTENANCE
(
v_userType IN VARCHAR2 DEFAULT NULL,
cv_1 OUT VARCHAR2
)
AS
BEGIN
IF UPPER(v_userType)='INTERNAL' THEN
select PARAMETER_VALUE INTO cv_1 from FIC_PARAMETER WHERE PARAMETER_NAME = 'MAINTENANCE_MODE_INTERNAL';
ELSIF UPPER(v_userType)='EXTERNAL' THEN
select PARAMETER_VALUE INTO cv_1 from FIC_PARAMETER WHERE PARAMETER_NAME = 'MAINTENANCE_MODE_EXTERNAL';
END IF;
END;
Fixed. The issue was that using a wrong connection string in web.config.

ORA-06550: line 1, column 7:\nPLS-00905: object TEST.CMPPROJECTPROC is invalid\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"}

I have created a procedure in oracle to insert data into table.When i call the procedure from asp.net webservices, its invoking the following error..
"ORA-06550: line 1, column 7:\nPLS-00905: object TEST.CMPPROJECTPROC is invalid\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored"}"
My procedure code is
CREATE OR REPLACE PROCEDURE CMPPROJECTPROC (
p_projectname CMPPROJECT.PROJECTNAME%TYPE,
p_description CMPPROJECT.DESCRIPTION%TYPE,
p_company CMPPROJECT.COMPANY%TYPE,
p_projectstatus CMPPROJECT.PROJECTSTATUS%TYPE,
p_websiteurl CMPPROJECT.WEBSITEURL%TYPE,
p_completedin CMPPROJECT.COMPLETEDIN%TYPE,
p_startedin CMPPROJECT.STARTEDIN%TYPE,
p_status CMPPROJECT.STATUS%TYPE)
IS
BEGIN
INSERT INTO CMPPROJECT (PROJECTNAME,DESCRIPTION,COMPANY,PROJECTSTATUS,WEBSITEURL,COMPLETEDIN,STARTEDIN,STATUS)
VALUES (p_projectname,p_description,p_company,p_projectstatus,p_websiteurl,p_completedin,p_startedin,p_status);
COMMIT;
END;
My webservice code is
[WebMethod]
public void Insert(string name, string description, int companyName, int projectStatus, string websiteurl, string completedin, string startredin, int status)
{
cmd = con.CreateCommand();
con.Open();
//cmd.CommandText = "CMPPROJECTPROC";
cmd = new OracleCommand("CMPPROJECTPROC", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("p_projectname", OracleDbType.Varchar2).Value = name;
cmd.Parameters.Add("p_description", OracleDbType.Varchar2).Value = description;
cmd.Parameters.Add("p_company", OracleDbType.Int16).Value = companyName;
cmd.Parameters.Add("p_projectstatus", OracleDbType.Int16).Value = projectStatus;
cmd.Parameters.Add("p_websiteurl", OracleDbType.Varchar2).Value = websiteurl;
cmd.Parameters.Add("p_completedin", OracleDbType.Varchar2).Value = completedin;
cmd.Parameters.Add("p_startedin", OracleDbType.Varchar2).Value = startredin;
cmd.Parameters.Add("p_status", OracleDbType.Int16).Value = status;
cmd.ExecuteNonQuery();
con.Close();
}
The stored procedure in the database is invalid. It will have to be compiled again. It may throw errors.
A procedure will be invalidated, when anything changes in the database the procedure was compiled against. For example if you changed the table the procedure is using, it has to be recompiled or you will get this error message.
You can recompile your stored procedure by doing this:
ALTER PROCEDURE TEST.CMPPROJECTPROC COMPILE;

Cannot find stored procedure

I have many stored procedure calls in my C# code, but only this one keeps failing. I'm running VS 2012 and SQL Server 2008 R2. My connection string is the same for all my stored procedures and I have the same permissions on all of them.
I get this error
Could not find stored procedure 'StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID'.
System.Exception {System.Data.SqlClient.SqlException}
on this line:
SqlDataReader dr = cmd.ExecuteReader();:
I have tried creating a new stored procedure with the same code, setting permissions, but it fails too.
public ArrayList DetailPreload(string bldg, string linePos, DateTime startD, string lineNo, string Pgrm, int apPos, string sessionID)
{
string strSQL = "StP_Map_Preload #bldg, #linePos, #startD, #lineNo, #Pgrm, #apPos, #sessionID";
ArrayList list = new ArrayList();
using (SqlConnection conStr = new SqlConnection(connM))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#bldg", bldg);
cmd.Parameters.AddWithValue("#linePos", linePos);
cmd.Parameters.AddWithValue("#startD", startD);
cmd.Parameters.AddWithValue("#lineNo", lineNo);
cmd.Parameters.AddWithValue("#Pgrm", Pgrm);
cmd.Parameters.AddWithValue("#apPos", apPos);
cmd.Parameters.AddWithValue("#sessionID", sessionID);
cmd.CommandText = strSQL;
cmd.Connection = conStr;
conStr.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
list.Add(new
{
company = dr["Company"],
Pgrm = dr["Pgrm"],
lineNum = dr["lineNum"],
lineStation = dr["lineStation"],
jobCount = dr["Job"],
item = dr["Item"],
qty = dr["Qty"],
partQty = dr["partQty"],
invCnt = dr["invCnt"],
runID = dr["runID"]
});
}
conStr.Close();
return list;
}
}
}
My stored procedure is in SQL Server and I can execute it in SQL Server
/*
StP_Map_Preload 'AA-12', '7', '09/19/2014', '', '247', 7, 'val2gxfh5ihoqy4tshzl4tp3'
*/
ALTER proc [dbo].[StP_Map_Preload]
#Bldg varchar(10),
#linePos varchar(5),
#startD date,
#LineNo varchar(5),
#Pgrm varchar(5),
#apPos int,
#sessionID varchar(50)
AS
BEGIN
declare #sql varchar(Max), #PST varchar(20),
#SI1 varchar(5), #SI2 varchar(5), #SI3 varchar(5),
#hasAP bit, #CCLen varchar,
#Co varchar(5), #CCs varchar(25), #lsGrp varchar(max)...
Change your line to
string strSQL = "StP_Map_Preload";
There is no need to list the parameters in the string that names the stored procedure.

Categories

Resources