I have an Oracle stored function which in Oracle is called as follows:
DECLARE
return_data varchar2(32767);
BEGIN
return_data := UCB_SYNC.GET_PROTEIN_DETAILS('PB0000007');
DBMS_OUTPUT.PUT_LINE(return_data);
END;
This works just fine so I now want to call it in C#; so I have the following code:
public string ExecuteStoredProcedure()
{
using (DbConnection cnn = GetNewConnection())
{
cnn.Open();
using (DbCommand cmd = cnn.CreateCommand())
{
cmd.CommandText = "ucb_sync.get_protein_details";
cmd.CommandType = CommandType.StoredProcedure;
DbParameter dbp = cmd.CreateParameter();
dbp.ParameterName = "protein_batch_id";
dbp.Value = "PB0000007";
dbp.DbType = DbType.String;
cmd.Parameters.Add(dbp);
DbParameter returnDbp = cmd.CreateParameter();
returnDbp.Direction = ParameterDirection.ReturnValue;
returnDbp.ParameterName ="result_data";
returnDbp.DbType = DbType.String;
cmd.Parameters.Add(returnDbp);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
throw e;
}
return returnDbp.Value.ToString();
}
}
}
This executes but the first parameter (protein_batch_id) gets passed through as an empty string. I can see this from my logs and the exception that comes back from the Oracle also confirms this.
It's a simple question; can anyone see what I'm doing wring to cause the first parameter to get passed through as an empty string?
Thanks for your help; it's dark, late and I need to get this done before going home!
You need to set the BindByName property of the command to true.
To do this replace the line
using (DbCommand cmd = cnn.CreateCommand())
with
using (OracleCommand cmd = cnn.CreateCommand())
and then add the line
cmd.BindByName = true;
to the other lines that configure cmd.
Related
The stored procedure in SQL works perfectly with the desired result.
ALTER PROCEDURE [dbo].[My_StoredProc]
(#autoidx int,
#r varchar(max) OUTPUT)
--with encryption
AS
BEGIN
-- ... some code here ...
END
Trying to call the stored procedure in VS 2019 using ODBC command but I get getting an error :
Procedure or function My_StoredProc expects parameter #autoidx, which was not supplied.
My code:
string connectionString = String.Format("DSN={0};uid=my_user;pwd=my_pwd", toolStripComboBoxDSN.Text);
// OdbcCommand DbCommand = new OdbcCommand("My_StoredProc", DbConnection);
// DbCommand.CommandType = CommandType.StoredProcedure;
//DbCommand.Parameters.AddWithValue("#autoidx", this.AutoIndex); //this.AutoIndex has value
//DbCommand.Parameters.Add("#r", OdbcType.VarChar,500);
//DbCommand.Parameters["#r"].Direction = ParameterDirection.Output;
//DbConnection.Open();
//DbCommand.ExecuteNonQuery();
//string s = (string)DbCommand.Parameters["#r"].Value;
//Code below is working. With a major change in CommandType
OdbcCommand DbCommand = new OdbcCommand(" EXEC dbo.My_StoredProc #autoidx=? ", DbConnection);
DbCommand.CommandType = CommandType.Text;
DbCommand.Parameters.Add("?", OdbcType.Int).Value = this.AutoIndex;
DbConnection.Open();
var s = DbCommand.ExecuteScalar();
I had one opinion:
1.- Try to change this
DbCommand.Parameters.AddWithValue("#autoidx", this.AutoIndex);
for this:
DbCommand.Parameters.Add("#autoidx", SqlDbType.Int);
DbCommand.Parameters["#autoidx"].Value = this.AutoIndex;
2.- Check you DbConnection, sometimes this contain other database for example db_developer instead of db_production.
Try to use the System.Data.SqlClient native SQL client to SQL Server, and use proper using blocks and proper parameter definition - something like this:
// standard SQL Client connection string
string connectionString = "......";
// define connection and command in proper "usinh" blocks
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand("dbo.My_StoredProc", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
// define parameters properly
cmd.Parameters.Add("#autoidx", SqlDbType.Int);
cmd.Parameters.Add("#r", SqlDbType.VarChar, -1).Direction = ParameterDirection.Output;
// set values to parametesr
cmd.Parameters["#autoidx"] = this.AutoIndex;
// open connection, execute procedure, close connection
conn.Open();
int rowsAffected = cmd.ExecuteNonQuery();
string s = cmd.Parameters["#r"].Value?.ToString();
conn.Close();
}
I need to know why I am still getting this error
Stored procedure expects parameter which was not supplied
But I am actually sending this parameter.
The stored procedure in the database looks like this:
CREATE PROCEDURE SVC_BUSCA_MEDIO_LANDING
(#rut VARCHAR)
AS
BEGIN
SELECT utm_source
FROM landing_formulario
WHERE rut = #rut
END
And my .net code:
string result = string.Empty;
string connString = System.Configuration.ConfigurationManager.AppSettings["StPazWeb"].ToString();
string SVC_BUSCA_MEDIO_LANDING = "SVC_BUSCA_MEDIO_LANDING";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
try
{
SqlCommand command = new SqlCommand(SVC_BUSCA_MEDIO_LANDING);
command.CommandType = CommandType.StoredProcedure;
command = new SqlCommand(command.CommandText, connection);
command.Parameters.AddWithValue("#rut", rut);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
result = (string)reader["utm_source"];
}
}
catch (SqlException ex)
{
throw new Exception("Oops!." + ex.Message);
}
}
return result.ToString();
Any idea what can be happening?
For some reason you create the command twice, with the second instantiation replacing the first, however on the second one you don't set the command type, and as a result your parameter is being ignored.
Try:
SqlCommand command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = SVC_BUSCA_MEDIO_LANDING;
command.Parameters.AddWithValue("#rut", rut);
You're using:
SqlCommand command = new SqlCommand(SVC_BUSCA_MEDIO_LANDING);
but you're reseting the command at:
command = new SqlCommand(command.CommandText, connection);
Try instead:
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "SVC_BUSCA_MEDIO_LANDING";
command = new SqlCommand(command.CommandText, connection);
command.Parameters.AddWithValue("#rut", rut);
I need to call to some function and procedures that in packages in Oracle.
I never worked with oracle, and i know only basic staff like insert,update table, but now i need to call "vb_new_serial " function to get back from it integer here this function function vb_new_serial return integer;
This function is located in Packages VN_PKG -> vb_new_serial
Here my code that i tried after i did some reasearches:
using (var conn = new OracleConnection(strConn2))
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "vb_new_serial";
conn.Open();
using (var dr = cmd.ExecuteReader())
{
MessageBox.Show(dr.ToString());
}
}
}
Here the image
But here i did't get back nothing.
What i am doing wrong?
Is there any parameters need to add in oracle command ? because return value is the first parameter added to the oracle command.
Like this
cmd.Parameters.Add("Return_Value", OracleDbType.Int16,
ParameterDirection.ReturnValue);
You just need to change your code in order to get the integer that the Oracle function returns:
using (var conn = new OracleConnection(strConn2))
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "VN_PKG.vb_new_serial";
OracleParameter myReturn = new OracleParameter("myReturn", OracleDbType.Int32, ParameterDirection.ReturnValue);
cmd.Parameters.Add(myReturn);
conn.Open();
cmd.ExecuteNonQuery();
MessageBox.Show(myReturn.Value.ToString());
}
}
I am having a problem with an Output parameter in C#/Oracle. I have isolated the code that I need to get working.
This is part of a much larger SQL statement, so do not worry too much if it doesn't make sense. In short I need to copy a row, give it a new ID and return that new ID. I tried using "RETURNING" which did not work. I see no reason why the code below should not work, but I'm getting an "ORA-01036: illegal variable name/number" error. Can anyone see what I'm doing wrong?
using (OracleConnection conn = new OracleConnection(connString))
{
// Open connection and create command.
conn.Open();
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("outValue", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.CommandText = "SELECT seq.nextval INTO :outValue FROM dual";
try
{
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
// This is just to see the exception when it fails.
}
}
}
The name of the parameter doesn't match.
cmd.Parameters.Add(":outValue", OracleType.Int32).Direction.......;
^
I have also seen this variation on the query syntax
"BEGIN SELECT seq.nextval INTO :outValue FROM dual END;"
You are using named parameters. Try setting:
cmd.BindByName = true;
Have you tried 'returning' keyword like this?
This code works for me.
using (OracleConnection conn = new OracleConnection(connString))
{
// Open connection and create command.
conn.Open();
using (OracleCommand cmd = new OracleCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("outValue", OracleType.Int32).Direction = ParameterDirection.Output;
cmd.CommandText = "insert into table (id, value) values (seq.nextval, 'value') returning id into :outValue";
cmd.ExecuteNonQuery();
}
}
I am trying to call a stored procedure from my C# windows application. The stored procedure is running on a local instance of SQL Server 2008. I am able to call the stored procedure but I am not able to retrieve the value back from the stored procedure. This stored procedure is supposed to return the next number in the sequence. I have done research online and all the sites I've seen have pointed to this solution working.
Stored procedure code:
ALTER procedure [dbo].[usp_GetNewSeqVal]
#SeqName nvarchar(255)
as
begin
declare #NewSeqVal int
set NOCOUNT ON
update AllSequences
set #NewSeqVal = CurrVal = CurrVal+Incr
where SeqName = #SeqName
if ##rowcount = 0 begin
print 'Sequence does not exist'
return
end
return #NewSeqVal
end
Code calling the stored procedure:
SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();
SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter();
param = cmd.Parameters.Add("#SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";
SqlDataReader reader = cmd.ExecuteReader();
I have also tried using a DataSet to retrieve the return value with the same result. What am I missing to get
the return value from my stored procedure? If more information is needed, please let me know.
You need to add a ReturnValue-direction parameter to the command:
using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = parameterStatement.getQuery();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");
// #ReturnVal could be any name
var returnParameter = cmd.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnParameter.Direction = ParameterDirection.ReturnValue;
conn.Open();
cmd.ExecuteNonQuery();
var result = returnParameter.Value;
}
Setting the parameter's direction to ParameterDirection.ReturnValue instructs the SqlCommand to declare it as a variable and assign the stored procedure's return value to it (exec #ReturnValue = spMyProcedure...), exactly like you would write it in SQL.
I know this is old, but i stumbled on it with Google.
If you have a return value in your stored procedure say "Return 1" - not using output parameters.
You can do the following - "#RETURN_VALUE" is silently added to every command object. NO NEED TO EXPLICITLY ADD
cmd.ExecuteNonQuery();
rtn = (int)cmd.Parameters["#RETURN_VALUE"].Value;
The version of EnterpriseLibrary on my machine had other parameters.
This was working:
SqlParameter retval = new SqlParameter("#ReturnValue", System.Data.SqlDbType.Int);
retval.Direction = System.Data.ParameterDirection.ReturnValue;
cmd.Parameters.Add(retval);
db.ExecuteNonQuery(cmd);
object o = cmd.Parameters["#ReturnValue"].Value;
I had a similar problem with the SP call returning an error that an expected parameter was not included. My code was as follows.
Stored Procedure:
#Result int OUTPUT
And C#:
SqlParameter result = cmd.Parameters.Add(new SqlParameter("#Result", DbType.Int32));
result.Direction = ParameterDirection.ReturnValue;
In troubleshooting, I realized that the stored procedure was ACTUALLY looking for a direction of "InputOutput" so the following change fixed the problem.
r
Result.Direction = ParameterDirection.InputOutput;
This is a very short sample of returning a single value from a procedure:
SQL:
CREATE PROCEDURE [dbo].[MakeDouble] #InpVal int AS BEGIN
SELECT #InpVal * 2; RETURN 0;
END
C#-code:
int inpVal = 11;
string retVal = "?";
using (var sqlCon = new SqlConnection(
"Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
{
sqlCon.Open();
retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";",
sqlCon).ExecuteScalar().ToString();
sqlCon.Close();
}
Debug.Print(inpVal + " * 2 = " + retVal);
//> 11 * 2 = 22
ExecuteScalar(); will work, but an output parameter would be a superior solution.
You can try using an output parameter. http://msdn.microsoft.com/en-us/library/ms378108.aspx
Or if you're using EnterpriseLibrary rather than standard ADO.NET...
Database db = DatabaseFactory.CreateDatabase();
using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
{
db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);
db.ExecuteNonQuery(cmd);
var result = (int)cmd.Parameters["RetVal"].Value;
}
I see the other one is closed. So basically here's the rough of my code. I think you are missing the string cmd comment. For example if my store procedure is call:DBO.Test. I would need to write cmd="DBO.test". Then do command type equal to store procedure, and blah blah blah
Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;