oracle character to number conversion error from .net - c#

I have a procedure in oracle having input fields varchar2 and number. I am adding parameters from my .Net code using Oracle.DataAccess.dll. I am getting an exception like
ORA-06502: PL/SQL: numeric or value error: character to number conversion error\nORA-06512: at line 1
If I run procedure directly from oracle sql developer, it works fine.
code:-
OracleCommand cmd = (OracleCommand)_dbFactory.CreateCommand();
try
{
cmd.Connection = (OracleConnection)_conOracle;
_conOracle.Open();
cmd.CommandText = "SERVICE_STATUS";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.Add("PANUMBER", OracleDbType.Int32).Value = 10;
cmd.Parameters.Add("PA_LINK", OracleDbType.Varchar2).Value = "Test";
cmd.Parameters.Add("PO_MSG", OracleDbType.Varchar2, 4000).Direction = System.Data.ParameterDirection.Output;
try
{
cmd.ExecuteScalar();
}
catch(Exception ex1) {
log.Debug("Exception ex1 "+ ex1.Message+" inner--"+ex1.InnerException);
}
string isValid = cmd.Parameters["PO_MSG"].Value.ToString();
if (isValid == "SUCCESS")
return true;
else
return false;
}
catch (Exception ex)
{
throw ex;
}
finally
{
_conOracle.Close();
}
procedure
create or replace
PROCEDURE SERVICE_STATUS( panumber number, pa_link varchar2 default NULL, po_msg OUT VARCHAR2 )
is
BEGIN
--logic comes here
END;

Whenever you have a procedure with one OUT parameter I would rather prefer to create a function instead.
Anyway, looks like you cannot change that, so take what you have.
Try to add the parameter like this:
cmd.Parameters.Add("PO_MSG", OracleDbType.Varchar2, 4000, null, ParameterDirection.Output);
cmd.Parameters["PO_MSG"].DbType = DbType.String;
(Only relevant for older version of ODP.NET providers)
The cmd.ExecuteScalar(); seems to be wrong. See documentation:
This method executes the query using the connection, and returns the
first column of the first row in the result set returned by the query.
You don't execute a query, you want to invoke a procedure. Use cmd.ExecuteNonQuery();
But the real issue should be the size of your output parameter. Apparently 4000 characters is not sufficient. As opposed to SQL (unless you set MAX_STRING_SIZE = EXTENDED) the max. size of VARCHAR2 datatype is 32767, see PL/SQL Program Limits.
So, change your parameter to
cmd.Parameters.Add("PO_MSG", OracleDbType.Varchar2, 32767).Direction = ParameterDirection.Output;

Related

C# : Getting error ORA-06550 while updating BLOB using stored procedure & ODP.NET

ORA-06550: line 1, column 7: PLS-00306: wrong number or types of
arguments in call to 'UPDATEPHOTO'
ORA-06550: line 1, column 7: PL/SQL: Statement
ignoredOracle.ManagedDataAccess.Client.OracleException
I don't know what is wrong either with procedure or my code.
Here's my stored procedure
create or replace
PROCEDURE UpdatePhoto
(
v_ac_photo_fileName IN VARCHAR2 DEFAULT NULL ,
v_ac_photo_contentType IN VARCHAR2 DEFAULT NULL ,
v_ac_photo_Data IN BLOB DEFAULT NULL ,
v_ac_uniqueID IN VARCHAR2 DEFAULT NULL
)
AS
BEGIN
UPDATE account_table
SET ac_photo_fileName = v_ac_photo_fileName,
ac_photo_contentType = v_ac_photo_contentType,
ac_photo_Data = v_ac_photo_Data
WHERE ac_uniqueID = v_ac_uniqueID;
END;
Here's my C# code:
public int UpdatePhoto(BO nBo)
{
OracleConnection ocon = new OracleConnection(orastr);
OracleCommand ocmd = new OracleCommand("UpdatePhoto", ocon);
ocmd.CommandType = CommandType.StoredProcedure;
ocon.Open();
try
{
ocmd.Parameters.Add("ac_uniqueID", nBo.account_uniqueID);//String
ocmd.Parameters.Add("ac_photo_fileName", nBo.account_photo_fileName);//string
ocmd.Parameters.Add("ac_photo_contentType", nBo.account_photo_contentType);//string
ocmd.Parameters.Add("ac_photo_Data", nBo.account_photo_Data);// (Byte[] photo data)
// tried these also
ocmd.Parameters.Add("ac_uniqueID", OracleDbType.Varchar2, ParameterDirection.Input).Value = nBo.account_uniqueID;
ocmd.Parameters.Add("ac_photo_fileName", OracleDbType.Varchar2, ParameterDirection.Input).Value = nBo.account_photo_fileName;
ocmd.Parameters.Add("ac_photo_contentType", OracleDbType.Varchar2, ParameterDirection.Input).Value = nBo.account_photo_contentType;
ocmd.Parameters.Add("ac_photo_Data", OracleDbType.Blob, ParameterDirection.Input).Value = nBo.account_photo_Data;
return ocmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
ocon.Dispose();
ocon.Close();
nBo = null;
}
}
Check out this post:
How to Update a BLOB column, error ORA-00932, while Insert works
I can't say for sure this is your issue, but per this post if you have BLOBs as parameters, you need to list them first in the parameter list for this to work. I have no idea why, but at the time I tried it both ways, and sure enough it worked when the BLOB was first, and it did not when it wasn't. I know, it makes no sense.
Alternatively, if you set the BindByName property of your OracleCommand object to true, this should also work. I'd try both to be sure.
One caveat: the post I referenced is for an insert function, not a stored procedure, so it's possible there is a difference.

Error converting nvarchar to data type int

I am getting this error when I try to call my stored procedure form code behind in my website. I have been stuck for quite a while now, as I do not know anywhere I am converting or declaring a value as an integer. This is my SQL statement:
create procedure GetRepPhoneID
#Rep nvarchar(100),
#phoneID nvarchar(100) output
as
set #phoneID = (select concat(CustomerRepPh, '~', cast(RepID as nvarchar(100))) as 'PhoneAndID'
from Reps
where CustomerRep=#Rep)
return #phoneID
go
Then from my c# code behind I am trying to call the stored procedure:
public static string GetRepPhone(string Rep)
{
string Connection = WebConfigurationManager.ConnectionStrings["JDC_DatabaseConnectionString"].ConnectionString;
SqlConnection sqlConnection = new SqlConnection(Connection);
//This funciton will take all of the values and create them.
try
{
sqlConnection.Open();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
SqlCommand cmd = new SqlCommand();
cmd.Connection = sqlConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetRepPhoneID"; //getting the procedure created in SQL.
SqlParameter CustomerParam = new SqlParameter();
CustomerParam.ParameterName = "Rep";
CustomerParam.SqlDbType = SqlDbType.NVarChar;
CustomerParam.Value = Rep;
CustomerParam.Direction = ParameterDirection.Input;
//We are using an output parameter not a return one because it is a string.
SqlParameter ReturnParam = new SqlParameter("phoneID", SqlDbType.NVarChar, 100);
ReturnParam.Direction = ParameterDirection.Output;
cmd.Parameters.Add(CustomerParam);
cmd.Parameters.Add(ReturnParam);
cmd.ExecuteNonQuery();
sqlConnection.Close();
return ReturnParam.Value.ToString();
}
I am doing the same thing multiple times in my code, but they all return integers so there has been no error thrown so I know it should work. The error is being thrown on the cmd.ExecuteNonQuery() line. The exact error is:
Conversion failed when converting the nvarchar value '(111)222-6666~29' to data type int.
I understand that I cannot convert that string to an integer, but I do not see anywhere in my code I am declaring an integer, or I am trying to convert.
Any help will be appreciated. Thanks.
You are confusing a RETURN value for an OUTPUT parameter. A RETURN is an optional status code of type INT. Declare another parameter as OUTPUT.
Meaning, this is invalid in the Stored Procedure:
return #phoneID
Instead, add #phoneID nvarchar(100) OUTPUT to the parameter list and remove the DECLARE #PhoneID:
CREATE PROCEDURE GetRepPhoneID
(
#Rep NVARCHAR(100),
#phoneID NVARCHAR(100) OUTPUT
)
AS
SET NOCOUNT ON;
SELECT #phoneID = concat(CustomerRepPh, '~', RepID)
FROM Reps
WHERE CustomerRep = #Rep;
The above represents the entire proc. You don't need the RETURN or the SET.
Then in the C# code, you need to change how that parameter is specified:
SqlParameter ReturnParam = new SqlParameter("phoneID", SqlDbType.NVarChar, 100);
ReturnParam.Direction = ParameterDirection.Output;
Then remove this line as it is not needed since the value of the parameter will remain after the connection is closed:
string PhoneAndID = cmd.Parameters[1].Value.ToString();
And change the return to be:
return ReturnParam.Value.ToString();
Lastly, you probably need to update the declaration of the input param as follows:
SqlParameter CustomerParam = new SqlParameter("Rep", SqlDbType.NVarChar, 100);
CustomerParam.Value = Rep;
CustomerParam.Direction = ParameterDirection.Input;

SQL Server not passing decimal value through to C#

I am trying to call a function that returns a decimal value to my C# website. When I call the function inside SQL Server the trailing decimal values are present. But when it gets passed into C# the trailing decimals are missing.
This is my SQL Server stored procedure being called:
declare #MonthlyTotal as decimal(10,2)
set #MonthlyTotal=(select cast((Linetotal * Subtotal) as decimal(10,2)))
return #MonthlyTotal
Inside my C# server code I am receiving the stored procedure value. But it does not come with the trailing decimals.
SqlConnection sqlConnection = new SqlConnection(Connection);
SqlCommand cmd4 = new SqlCommand();
cmd4.Connection = sqlConnection;
cmd4.CommandType = CommandType.StoredProcedure;
cmd4.CommandText = "GetTBSMonthlyTotalService";
SqlParameter JobParam = new SqlParameter("MonthlyTotal", SqlDbType.Decimal, 10);
JobParam.Precision = 10;
JobParam.Scale = 2;
JobParam.Direction = ParameterDirection.ReturnValue;
cmd4.Parameters.Add(JobParam);
try
{
sqlConnection.Open();
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
cmd4.ExecuteNonQuery();
double ID = Double.Parse((cmd4.Parameters[0].Value.ToString()));
sqlConnection.Close();
return ID;
The return value of a stored procedure can only be an integer type (INT, BIGINT - see the relevant MSDN docs on RETURN) and it's only used to signal success (or failure) of the stored procedure.
If you need to return anything else - including decimal - you need to use either an OUTPUT parameter, or a SELECT statement that selects that value as a result set for the stored procedure.

Stored Procedure returns nothing

This might be a simple fail on my part, but I just can't figure out where or how.
I've been coding a windows service that is doing a bunch of things. One of which is inserting and getting data from a MS Sql 2005 database through stored procedures.
The following code is part of a windows service and now also a windows form, where both produce the same empty result.
try
{
SqlCommand cmd = new SqlCommand("U_RfId_ProductNumberGet", connectionRFID);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
//SqlParameter paramProd = new SqlParameter();
SqlParameter paramOut = new SqlParameter();
paramOut.ParameterName = "#ProductInformation";
paramOut.Direction = System.Data.ParameterDirection.Output;
paramOut.SqlDbType = System.Data.SqlDbType.VarChar;
paramOut.Size = 50;
cmd.Parameters.Add(paramOut);
cmd.Parameters.AddWithValue("#ProductNumber", content); //content = "1" for testing
connectionRFID.Open();
textBox1.Text = (String)paramOut.Value;
//cmd.Parameters["#ProductInformation"].Value.ToString();
connectionRFID.Close();
}
catch (Exception ex)
{ textBox1.Text = ex.Message;
connectionRFID.Close();
}
And then there's the SP the code is calling. I've tried changing it to only return a resultset instead of a scalar output parameter and then the call to the SP works, but I'd prefer to use the scalar values.
CREATE PROCEDURE U_RfId_ProductNumberGet
#ProductInformation varchar(50) OUTPUT,
#ProductNumber varchar(8)
AS
BEGIN TRAN
SET NOCOUNT ON;
BEGIN
SELECT #ProductInformation
= CAST(vareNummer AS varchar(10))
+ '-' + CAST(vareTekst AS varchar(30))
FROM VareNummerVareTekst
WHERE ProductNumber = #ProductNumber
END
COMMIT TRAN
As a side note: If I execute the SP through SQL Management Studio I get a valid result.
Anyone notice what I've forgotten?
You forgot to execute the command.
cmd.Execute(); // to get a resultset
or
cmd.ExecuteNonQuery(); // to get output parameters but no resultset
should do it depending on whether or not you want a resultset.
you have to use ExecuteNonQuery on command object. SqlCommand Executenonquery
connectionRFID.Open();
cmd.ExecuteNonQuery(); // this missing from your code
textBox1.Text = (String)paramOut.Value;

Weird behavior with two output parameters in a stored proc called from c#

I've modified an existing strored procedure. It originally had one ouput parameter in the stored proc and it was set up as follows in the c# code that called it:
cmd.Parameters.Add("#Var1Param", SqlDbType.BigInt);
if (Var1 == 0)
cmd.Parameters["#Var1"].Value = DBNull.Value;
else
cmd.Parameters["#Var"].Value = Var1;
cmd.Parameters["#Var1"].Direction = ParameterDirection.InputOutput;
cmd.ExecuteNonQuery();
// Get Var1
Var1= dataMorph.ToInt64(cmd.Parameters["#Var1"].Value.ToString());
Just to clarify, this parameter was declared as OUTPUT in the stored proc but as inputoutput in the C# code. This worked fine.
I have added another parameter to the same stored procedure and I want to retrieve both from the C# code. The C# code now is as follows:
SqlParameter Var1Param;
if (VAR1 == 0)
Var1Param = new SqlParameter("#Var1", DBNull.Value);
else
Var1Param = new SqlParameter("#Var1",Var1) ;
Var1Param.Direction = ParameterDirection.InputOutput ;
cmd.Parameters.Add(Var1Param);
Again this parameter is declared as output in the stored proc but inputoutput in the c# code.
Here is the new parameter. This is declared as output in the stored procedured. Here is the C# code.
SqlParameter Var2Param = new SqlParameter("#Var2", 0);
Var2Param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(Var2Param);
I only want to output the second parameter as you can see. The assignment of 0 to this parameter seems to be a standard practice despite the fact it's an output variable only. I'm not sure if need to give it a type.
Now the execution
// Execute
cmd.ExecuteScalar();
connection.Close();
// Get DonationID
Var1 = dataMorph.ToInt64(cmd.Parameters["#Var1"].Value.ToString());
//Get Supersession Daf ID return param to see if new DAF was created
Var2 = dataMorph.ToInt64(cmd.Parameters["#Var2"].Value.ToString());
What happens is that both the var1 and vaf2 parameters contain the value that was assigned to #Var2 parameter in the stored procedure. I have read that any number of parameters and parameter types can be used but it seems like the value assigned to #Var2 is overwriting the Value that had been passed in or assigned to Var1.
Any advice? I know I can work around this by having multiple result sets and putting my output values in the second result set but I'd rather not deal with Kludges unless I have to. I've seen a lot of posts about the odd state of parameters after they return from stored procs and are accessed in c#. Is this type of behavior a bug?
I will point out that I'm using executenonquery because the SP does an update. sarfeast is using execute scalar. I'm assuming that this shouldn't make any difference but I'll ask if anyone has any ideas on why this is happening. I modified the code by specifying sizes for the sqlparameters and now the value for var2 is showing up in var1 and var2 is Null!!!
Any advice would be appreciated.
The following code seems to work just fine so perhaps this has something to do with the logic in your stored procedure?
CREATE PROCEDURE Outs
#var1 INT OUTPUT,
#var2 INT OUTPUT
AS
BEGIN
SELECT #var1 = 1,
#var2 = 2
END
GO
var connectionstring = #"server=rickshaw;database=becak;Trusted_Connection=true;";
using(var conn = new SqlConnection(connectionstring))
using(var cmd = new SqlCommand("Outs", conn))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
conn.Open();
cmd.Parameters.Add("#var1", SqlDbType.BigInt);
cmd.Parameters.Add("#var2", 0);
cmd.Parameters["#var1"].Value = DBNull.Value;
cmd.Parameters["#var1"].Direction = ParameterDirection.InputOutput;
cmd.Parameters["#var2"].Value = 0;
cmd.Parameters["#var2"].Direction = ParameterDirection.Output;
cmd.ExecuteScalar();
conn.Close();
var var1 = cmd.Parameters["#var1"].Value;
var var2 = cmd.Parameters["#var2"].Value;
Console.WriteLine("var1=" + var1);
Console.WriteLine("var2=" + var2);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.ReadLine();

Categories

Resources