I have a stored procedure which accepts one string parameter, below is my code
var databaseContext = (DbContext)this.ManagementContext;
databaseContext.Database.Connection.Open();
using (var command = databaseContext.Database.Connection.CreateCommand())
{
command.CommandText = "StoredProcName";
command.CommandType = CommandType.StoredProcedure;
DbParameter param = command.CreateParameter();
param.DbType = DbType.String;
param.Direction = ParameterDirection.Input;
param.Value = "Vikash";
command.Parameters.Add(param);
using (var reader = command.ExecuteReader())
My stored procedure is not getting value in parameter.
You have missed your ParameterName in your code. Try this,
using (var ctx = new StOflowContext())
{
ctx.Database.Connection.Open();
using (var command = ctx.Database.Connection.CreateCommand())
{
command.CommandText = "StoredProcedureName";
command.CommandType = CommandType.StoredProcedure;
DbParameter param = command.CreateParameter();
param.ParameterName = "#paramName";
param.DbType = DbType.String;
param.Direction = ParameterDirection.Input;
param.Value = "Vikash";
command.Parameters.Add(param);
using (var reader = command.ExecuteReader())
{
while(reader.Read())
{
}
}
}
}
I tried this way and it works fine.
var dateParameter = new SqlParameter { ParameterName = "CastID", Value = castMember, DbType = DbType.String, Direction = ParameterDirection.Input };
command.Parameters.Add(dateParameter);
If your stored procedure is named "StoredProcName", and execute with parameter named "Para1".
var executedResult =
((IObjectContextAdapter) this).databaseContext.ExecuteStoreCommand(
"StoredProcName #Para1", "Vikash");
then, you'll get stored procedure result in "executedResult".
Related
This is the output when I desc the stored procedure:
desc procedure_name
VCOMPTE VARCHAR2 IN
VRESULT REF CURSOR OUT
CLIENT_NO VARCHAR2(6) OUT
ACCT_NAME VARCHAR2(35) OUT
NCG VARCHAR2(6) OUT
NCG_DESC VARCHAR2(35) OUT
AGENCE VARCHAR2(5) OUT
TEL VARCHAR2(50) OUT
This is the C# code I am using to execute it:
public void Validate(string account_num)
{
OracleConnection conn = new OracleConnection(HelperClass.GetConstring());
OracleCommand _cmdObj = conn.CreateCommand();
_cmdObj.CommandText = "pk_xxx.procedure_name";
_cmdObj.CommandTimeout = 1680;
_cmdObj.CommandType = System.Data.CommandType.StoredProcedure;
OracleParameter para_account_num = new OracleParameter();
para_account_num.ParameterName = "VCOMPTE";
para_account_num.OracleDbType = OracleDbType.Varchar2;
para_account_num.Direction = System.Data.ParameterDirection.Input;
para_account_num.Value = account_num;
_cmdObj.Parameters.Add(para_account_num);
OracleParameter VRESULT = new OracleParameter();
VRESULT.ParameterName = "VRESULT";
VRESULT.OracleDbType = OracleDbType.RefCursor;
VRESULT.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(VRESULT);
OracleParameter client_no = new OracleParameter();
client_no.ParameterName = "CLIENT_NO";
client_no.OracleDbType = OracleDbType.Varchar2;
client_no.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(client_no);
OracleParameter acct_name = new OracleParameter();
acct_name.ParameterName = "ACCT_NAME";
acct_name.OracleDbType = OracleDbType.Varchar2;
acct_name.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(acct_name);
OracleParameter ncg = new OracleParameter();
ncg.ParameterName = "NCG";
ncg.OracleDbType = OracleDbType.Varchar2;
ncg.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(ncg);
OracleParameter tr_desc = new OracleParameter();
tr_desc.ParameterName = "NCG_DESC";
tr_desc.OracleDbType = OracleDbType.Varchar2;
tr_desc.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(tr_desc);
OracleParameter AGENCE = new OracleParameter();
AGENCE.ParameterName = "AGENCE";
AGENCE.OracleDbType = OracleDbType.Varchar2;
AGENCE.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(AGENCE);
OracleParameter TEL = new OracleParameter();
TEL.ParameterName = "TEL";
TEL.OracleDbType = OracleDbType.Varchar2;
TEL.Direction = System.Data.ParameterDirection.ReturnValue;
_cmdObj.Parameters.Add(TEL);
try
{
conn.Open();
OracleDataReader reader = _cmdObj.ExecuteReader();
while (reader.Read())
{
//I will use the data
}
}
catch (Exception xc)
{
//catch xc
}
}
But I get an error
Wrong number or types of arguments in call to "procedure_name"."
Debugging is difficult for me because I don't have direct access to the Oracle database, and I am not sure what I am doing wrong. I have successfully executed other stored procedures in the same database. Thanks in advance!
ExecuteReader() is used only for functions, not for procedures. You must use ExecuteNonQuery()
After ExecuteNonQuery() you have to read the result, e.g.
_cmdObj.ExecuteNonQuery();
OracleDataReader reader = ((OracleRefCursor)VRESULT.Value).GetDataReader();
Or create a FUNCTION like
FUNCTION function_name RETURNS SYS_REFCURSOR
VCOMPTE VARCHAR2 IN
CLIENT_NO VARCHAR2(6) OUT
ACCT_NAME VARCHAR2(35) OUT
NCG VARCHAR2(6) OUT
NCG_DESC VARCHAR2(35) OUT
AGENCE VARCHAR2(5) OUT
TEL VARCHAR2(50) OUT
And call it like this
OracleCommand _cmdObj = conn.CreateCommand();
_cmdObj.CommandText = "pk_xxx.procedure_name";
_cmdObj.CommandType = CommandType.StoredProcedure;
_cmdObj.Parameters.Add("res", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
_cmdObj.Parameters.Add("VCOMPTE", OracleDbType.Varchar2, ParameterDirection.Input).Value = account_num;
_cmdObj.Parameters.Add("CLIENT_NO", OracleDbType.Varchar2, ParameterDirection.Output);
_cmdObj.Parameters.Add("ACCT_NAME", OracleDbType.Varchar2, ParameterDirection.Output);
...
OracleDataReader reader = _cmdObj.ExecuteReader();
Maybe have a look at Data Provider for .NET Developer's Guide
I have error when I try to pass parameter to stored procedure using DbCommand
Error returned:
Procedure or function 'Procedure_Name' expects parameter '#TEID', which was not supplied.
These are my procedure parameters:
#PageNumber INT = 1,
#PageSize INT = 50,
#StartTime nvarchar(max) = -1 ,
#EndTime nvarchar(max) = -1 ,
#Month NVARCHAR(2) = -1,
#Year NVARCHAR(4) = -1,
#Day NVARCHAR(2) = -1,
#Hour NVARCHAR(2)=-1,
#TEID nvarchar(max) ,
#IgnoreIdlingTime int=120,
#DrivingTime int=300,--5 minutes by default
#CalculationFactor nvarchar(10)='speed'
My code to execute procedure and pass parameters:
using (var context = new GPSModel())
{
context.Database.Initialize(force: false);
// Create a SQL command to execute the stored procedure
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandText = "Procedure_Name";
DbParameter TEIDParam = cmd.CreateParameter();
TEIDParam.ParameterName = "#TEID";
TEIDParam.DbType = System.Data.DbType.String;
TEIDParam.Direction = ParameterDirection.Input;
TEIDParam.Value = TEID;
cmd.Parameters.Add(TEIDParam);
context.Database.Connection.Open();
var reader = cmd.ExecuteReader();
}
I tried to remove # sign and send SqlParameter instead of DbParameter but still I have the same issue.
Is there any other way to do that where my stored procedure is very complex and contains multi sets
Thanks...
You can use the following code to solve the error. I have added cmd.CommandType = CommandType.StoredProcedure;. Now it works properly.
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Procedure_Name";
DbParameter TEIDParam = cmd.CreateParameter();
TEIDParam.ParameterName = "#TEID";
TEIDParam.DbType = System.Data.DbType.String;
TEIDParam.Direction = ParameterDirection.Input;
TEIDParam.Value = TEID;
cmd.Parameters.Add(TEIDParam);
When you are using stored procedure you have to set CommandType property to StoredProcedure, and then you should set the CommandText property to the name of the stored procedure. The command executes this stored procedure when you call one of the Execute methods.
FOR EF core it can be done using fromSQL()
var tbl = new DataTable();
tbl.Columns.Add("id", typeof(string));
foreach (var item in imageChunkRequest.ChunkNames)
{
tbl.Rows.Add(item);
}
SqlParameter Parameter = new SqlParameter();
Parameter.ParameterName = "#udt";
Parameter.SqlDbType = SqlDbType.Structured;
Parameter.Value = tbl;
Parameter.TypeName = "dbo.StringList";
_dbContext.Set<T>().FromSql("EXEC dbo.FindChunks #udt",Parameter);
I have a stored procedure that accepts an input and returns multiple columns. The stored procedure works when I execute it from SSMS and also inside of VS 2013. However when I try and execute it using SqlCommand.ExecuteReader the reader doesn't have any rows in it. If I remove the output parameters from the proc and from the SqlCommand, while still keeping the one input parameter, I am able to return the row that I am looking for.
Here is the stored proc
create Proc sp_ReturnSingleGame
#GameName varchar(100) output,
#PlatformName varchar(50) output,
#ConditionShortDescription varchar(30) output,
#RetailCost decimal(6,2) output,
#InStock bit output,
#GameID int
AS
select #GameName = GameName, #PlatformName = PlatformName,
#ConditionShortDescription = ConditionShortDescription, #RetailCost = RetailCost
from Games inner join Condition
on Games.ConditionID = Condition.ConditionID
inner join ConsolePlatform
on Games.PlatformID = ConsolePlatform.PlatformID
Where Games.GameID = #GameID
if exists (select GameID
From SaleItemized
Where GameID = #GameID)
Begin
set #InStock = 1;
end
else
Begin
set #InStock = 0;
end
Here is my C# code
public Game ReturnSingleGame(int gameId)
{
SqlConnection connection = new SqlConnection(#"server=mylaptop; integrated security=true; database=GameStoreDB;");
SqlCommand command = this.ReturnCommandForSp_ReturnSingleGame(connection, gameId);
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows == true)
{
reader.Read();
game.GameId = gameId;
game.GameName = reader["GameName"].ToString();
game.PlatformName = reader["PlatformName"].ToString();
game.RetailCost = (decimal) reader["RetailCost"];
}
else
{
var exception = new ApplicationException("Game was not found");
throw exception;
}
}
catch (Exception)
{
throw;
}
finally
{
connection.Close();
}
return game;
}
private SqlCommand CommandForSp_ReturnSingleGame(SqlConnection connection, int gameId)
{
string storedProc = #"dbo.sp_ReturnSingleGame";
SqlCommand command = new SqlCommand(storedProc, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#GameName", SqlDbType.VarChar, 100, "GameName");
command.Parameters["#GameName"].Direction = ParameterDirection.Output;
command.Parameters.Add("#PlatformName", SqlDbType.VarChar, 50, "PlatformName");
command.Parameters["#PlatformName"].Direction = ParameterDirection.Output;
command.Parameters.Add("#ConditionShortDescription", SqlDbType.VarChar, 30, "ConditionShortDescription");
command.Parameters["#ConditionShortDescription"].Direction = ParameterDirection.Output;
command.Parameters.Add("#RetailCost", SqlDbType.Decimal);
command.Parameters["#RetailCost"].SourceColumn = "RetailCost";
command.Parameters["#RetailCost"].Precision = 6;
command.Parameters["#RetailCost"].Scale = 2;
command.Parameters["#RetailCost"].Direction = ParameterDirection.Output;
command.Parameters.Add("#InStock", SqlDbType.Bit);
command.Parameters["#InStock"].SourceColumn = "InStock";
command.Parameters["#InStock"].Direction = ParameterDirection.Output;
command.Parameters.Add("#GameID", SqlDbType.Int).Value = gameId;
command.Parameters["#GameID"].SourceColumn = "GameID";
command.Parameters["#GameID"].Direction = ParameterDirection.Input;
command.Prepare();
return command;
}
Stored procedure provided by you actually doesn't return any rows of data.
All it does - is just set output parameters.
So you don't need any SqlDataReader to retrieve there parameters.
Just call command.ExecuteNonQuery() and then get your parameters values from command.Parameters["#GameName"].Value and so on.
Agree with Andy.
For you snippet from one of my project is:`
DbCommand Cmd = null;
using (DataClient client = new DataClient())
{
SqlParameter[] parameters = new SqlParameter[2];
parameters[0] = new SqlParameter("#ID", SqlDbType.VarChar);
parameters[0].Size = 10;
parameters[0].Direction = ParameterDirection.Output;
parameters[1] = new SqlParameter("#YourParameterName", SqlDbType.VarChar);
parameters[1].Value = Class.PropertyName;
parameters[2] = new SqlParameter("#Year", SqlDbType.Int);
client.ExecuteNonQuery("ReturnCommandForSp_ReturnSingleGame", CommandType.StoredProcedure, parameters, ref Cmd);
Then retrieve it like this
int yourReturnValue= Convert.ToInt32(Cmd.Parameters["#ID"].Value);
}
Hope it helps.
How do I get variable #Test that was changed in query?
const string query = #"SET #Test = 2;";
using (var connection = new SqlConnection(conStr))
{
connection.Open();
var command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#Test", 1);
var r = command.ExecuteReader();
// command.Parameters["#Test"].Value == 1
// r hasn't any variables
}
ADDED:
I've solve this problem withoute creating stored procedure
const string query = #"SET #Test = 2;";
using (var connection = new SqlConnection(conStr))
{
connection.Open();
var command = new SqlCommand(query, connection);
SqlParameter par = command.Parameters.Add("#Test", SqlDbType.NVarChar, 15);
par.Direction = ParameterDirection.Output;
command.ExecuteNonQuery();
// par.Value now contain 2
}
Both ansvers help!
Firstly, in your stored procedure the parameter needs to be marked as OUTPUT
CREATE PROC MyQuery
#Test INT OUTPUT
AS
SET #Test = 2
Then, when constructing the c# code, instead of using AddWithValue, be more explicit in your creation of a SqlParameter, namely marking it as Input/Output.
var command = new SqlCommand("MyQuery", connection);
command.CommandType = CommandType.StoredProcedure;
var param = command.CreateParameter();
param.Name = "#Test";
param.Type = DbType.Int;
param.Direction = ParameterDirection.InputOutput;
param.Value = 1;
Now once you execute your command:
command.ExecuteNonQuery(); // Could also be ExecuteReader, if you have a resultset too!
You can read the value of param, which should have changed to 2
if(param.Value == 2)
{ Console.WriteLine("WooHoo"); }
I have a stored procedure with an output parameter. How do I read this value using C# code?
I assume you use ADO.NET? If so, the SqlParameter class has the property "Direction". Set direction to output and after the query has executed you read the value from that parameter.
Something like this:
using (SqlCommand cmd = new SqlCommand("MyStoredProcedure", cn))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parm = new SqlParameter("#pkid", SqlDbType.Int);
parm.Value = 1;
parm.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm);
SqlParameter parm2 = new SqlParameter("#ProductName", SqlDbType.VarChar);
parm2.Size = 50;
parm2.Direction = ParameterDirection.Output; // This is important!
cmd.Parameters.Add(parm2);
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}