I have a problem calling my stored procedure in my database
this is my stored procedure in my database
DELIMITER $$
USE `sample`$$
DROP PROCEDURE IF EXISTS `sp_ReturnAttendanceInfo`$$
CREATE DEFINER=`root`#`192.168.%` PROCEDURE `sp_ReturnAttendanceInfo`(IN uname INT(4), IN daterange DATETIME)
BEGIN
SELECT shift_time.in, shift_time.out, MIN(perf_prog.start_time) AS start_time, MAX(perf_prog.end_time) AS end_time, perf_prog.date FROM perf_prog INNER JOIN Shifts ON perf_prog.emp_id = Shifts.emp_id
INNER JOIN shift_time ON Shifts.id = shift_time.id
WHERE perf_prog.emp_id = uname AND DATE(`date`) >= daterange
GROUP BY `date` ORDER BY `date` ;
END$$
DELIMITER ;
when i call this stored procedure in database query
like this
CALL sp_ReturnAttendanceInfo(0921, '2017-04-02')
it returns an output
but when i call it in my c#
using (MySqlConnection connection = new MySqlConnection(mysqlConnection))
{
connection.Open();
if (connection.State == System.Data.ConnectionState.Open)
{
using (MySqlCommand cmd = new MySqlCommand("sp_ReturnAttendanceInfo", connection))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#uname", username);
cmd.Parameters.AddWithValue("#date", date.ToString("yyyy-MM-dd"));
using (MySqlDataReader dataReader = cmd.ExecuteReader())
{
while (dataReader.Read())
{
}
}
}
}
}
i even checked the parametre im passing:
921
2017-04-04
but still i can't solve it. i even search the problem before creating a question, but i can't solve it. the error message is still the same
and this is the error:
Parameter 'daterange' not found in the collection.
at MySql.Data.MySqlClient.MySqlParameterCollection.GetParameterFlexible(String parameterName, Boolean throwOnNotFound)
at MySql.Data.MySqlClient.StoredProcedure.GetAndFixParameter(String spName, MySqlSchemaRow param, Boolean realAsFloat, MySqlParameter returnParameter)
at MySql.Data.MySqlClient.StoredProcedure.CheckParameters(String spName)
at MySql.Data.MySqlClient.StoredProcedure.Resolve(Boolean preparing)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
both the parameters you pass into the stored proc and the parameters that accept those values have to be the same, thus change:
cmd.Parameters.AddWithValue("#date", date.ToString("yyyy-MM-dd"));
to
cmd.Parameters.AddWithValue("#daterange", date.ToString("yyyy-MM-dd"));
Related
The Stored Procedure:
BEGIN
SELECT * FROM `user` WHERE `EmailAddress`= #p0 AND `Password` = #p1;
END
Where #p0 and #p1 are Varchar(100).
And the code:
using (MySqlConnection con = new MySqlConnection(Database.MySQLConstring))
{
using (MySqlCommand cmd = new MySqlCommand("LoginCheck", con))
{
cmd.CommandType = CommandType.StoredProcedure; //"LoginCheck"
cmd.Parameters.AddWithValue("email", Email);
cmd.Parameters.AddWithValue("password", Pword);
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
UserModel UM = new UserModel();
While (reader.Read())
{
UM.UserId = (int)reader["UserID"];
UM.DisplayName = (string)reader["DisplayName"];
UM.Moderator = (int)reader["Moderator"];
}
con.Close();
While(!string.IsNullOrEmpty(UM.DisplayName) && UM.UserId != 0)
{
Result = 1;
return UM;
}
Result = -1;
return UM;
}
}
The code runs succesfull until it comes to the while(reader.Read()) part, then it skips it and goes to the con.close(). No errors or exceptions are thrown. It worked when I was using it when everything was SQL and not MySQL ,but I need to get it working in MySQL.
When I run the stored Procedure itself in de databse then I get my result that I need. but when I use the code it will skip the While part of the code.
If I were going to execute a procedure that was declared as:
CREATE PROCEDURE x(em VARCHAR, pw VARCHAR) --declaration of parameters
BEGIN
SELECT * FROM `user` WHERE `EmailAddress`= em AND `Password` = pw;
END
I would ensure the parameters in my C# code were named the same as in the declaration of the stored procedure:
cmd.Parameters.Add(new MySqlParameter("em", Email));
cmd.Parameters.Add(new MySqlParameter("pw", Password));
I suspect that your query is not getting any rows, because the values you set never make it into the parameters, and are hence never used to query. reader.Read() returns false, because there are no rows. Also make sure that the values for EMail and Password that you're querying really do exist in the table
Try as a debugging thing, to make your query like:
SELECT UserID, DisplayName, Moderator FROM `user` WHERE `EmailAddress`= #p0 AND `Password` = #p1
UNION ALL
SELECT 0, CONCAT_WS(' ', 'There is no user with email/password of', #p0, '/', #p1), '' FROM DUAL;
Or however your parameters are named now..
Your reader.Read()should now return true because this query should always return a row, so inspect the value of DisplayName, it should tell what search terms were applied
I am fairly new to C# and I'm trying to set up call to a stored procedure in my database which takes one parameter.
I get the error "Procedure or function 'SP_getName' expects parameter '#username', which was not supplied. "
My Stored procedure works ok when I supply it with the parameter and I run it via SQL management studio.
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_getName]
#username = 'bob101'
SELECT 'Return Value' = #return_value
GO
However when I try and call it the error is with how I'm passing the parameter in, but I can't spot what the issue is.
//create a sql command object to hold the results of the query
SqlCommand cmd = new SqlCommand();
//and a reader to process the results
SqlDataReader reader;
//Instantiate return string
string returnValue = null;
//execute the stored procedure to return the results
cmd.CommandText = "SP_getName";
//set up the parameters for the stored procedure
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = "bob101";
cmd.CommandType = CommandType.Text;
cmd.Connection = this.Connection;
// then call the reader to process the results
reader = cmd.ExecuteReader();
Any help in spotting my error would be greatly appreciated!
I've also tried looking at these two posts, but I haven't had any luck:
Stored procedure or function expects parameter which is not supplied
Procedure or function expects parameter, which was not supplied
Thanks!
You have stated:
cmd.CommandType = CommandType.Text;
Therefore you are simply executing:
SP_getName
Which works because it is the first statement in the batch, so you can call the procedure without EXECUTE, but you aren't actually including the parameter. Change it to
cmd.CommandType = CommandType.StoredProcedure;
Or you can change your CommandText to:
EXECUTE SP_getName #username;
As a side note you should Avoid using the prefix 'sp_' for your stored procedures
And a further side note would be to use using with IDisposable objects to ensure they are disposed of correctly:
using (var connection = new SqlConnection("ConnectionString"))
using (var cmd = new new SqlCommand("SP_getName", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#username", SqlDbType.NVarChar).Value = "bob101";
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do something
}
}
}
I had this problem, but it wasn't about parameter name of Command Type.
My problem was that when C# calls SP, for each parameter that has no value passes 'default' keyword (i found it in SQL Profiler):
... #IsStop=0,#StopEndDate=default,#Satellite=0, ...
in my case my parameter Type was DateTime :
#StopEndDate datetime
. I Solved my problem by seting default value to this parameter in Stored Procedure :
#StopEndDate datetime=null
Try remove #:
cmd.Parameters.Add("username", SqlDbType.NVarChar).Value = "bob101";
I have a web service in C#, I use it to consults from tables, but I want to create a WebMethod to call a stored procedure and get back multiples output parameters. I can execute it with output parameters, it doesn't work when I try to call it whit outputs parameters.
This is a sample, I want to get back more that 2 parameters.
Stored procedure:
CREATE OR REPLACE PROCEDURE O_CAPEREZ.GIO_SP (
VNOMBRE IN VARCHAR2,
SALUDO OUT VARCHAR2 )
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (vNOMBRE);
SALUDO:= ('Hello: ' || vNOMBRE);
END;
And this is my code in the web service, when I execute it using output variables I get this error
[HYC00] [Oracle][ODBC]Optional feature not implemented
C# code:
[WebMethod]
public string AP_Data(string curp)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (OdbcConnection con = new OdbcConnection(constr))
{
OdbcCommand cmd = new OdbcCommand("{CALL GIO_SP(?,?)}", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#vNOMBRE", (curp));
cmd.Parameters.Add("#vNOMBRE", OdbcType.VarChar, 18);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Parameters["#SALUDO"].Direction = ParameterDirection.ReturnValue;
cmd.Connection.Close();
string ret = Convert.ToString(cmd.Parameters["#SALUDO"].Value);
return ret;
}
}
You have to add the parameter to the list even if you're not going to set a value there:
cmd.Parameters.Add("#SALUDO", OdbcType.VarChar, 18).Direction = ParameterDirection.Output;
I don't know the the Oracle flavor is different, but in SQL I use ParameterDirection.ReturnValue rather than ParameterDirection.Output.
here's how i do it in MS SQL server 2008 But notice the data type and the lenth of the variables your create must be the same in your table
the stored proc create code
USE DATABASE DATABASE_NAME
GO
CREATE PROC SP_METHOD
#ID_CATIGORY INT,
#NAME VARCHAR (50),
#DESCRIPTION VARCHAR (50)
AS
INSERT INTO TABLE_NAME
([ID_CAT]
,[NAME_PRODUCT]
,[DESC_PRODUCT]
)
VALUES
( #ID_CATIGORY
,#NAME
,#DESCRIPTION )
GO
in the c# code
// Create SqlConnection
SqlConnection conn= new SqlConnection(#"Server=server_name;
DataBase=your_data_base_name;Integrated Security=false;User
Id=user_id;Password=password");
// Open the Connection
if (sqlconnection.State != ConnectionState.Open)
{
conn= .Open();
}
// execute stored_procedure method don't change this
public void ExecuteCommand(string stored_procedure, SqlParameter[] param)
{
SqlCommand sqlcomd = new SqlCommand();
sqlcomd.CommandType = CommandType.StoredProcedure;
sqlcomd.CommandText = stored_procedure;
sqlcomd.Connection = sqlconnection;
if (param !=null)
{
sqlcomd.Parameters.AddRange(param);
}
sqlcomd.ExecuteNonQuery();
}
// close connection method
public void close_conn()
{
if (sqlconnection.State == ConnectionState.Open)
{
sqlconnection.Close();
}
}
// execute and retrieving data Method
public void Add_product(int ID_cat ,string Name_Product,string
Des_Product)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("#ID_CAT", SqlDbType.Int);
param[0].Value = ID_cat;
param[1] = new SqlParameter("#NAME_PRODUCT", SqlDbType.VarChar, 50);
param[1].Value = Name_Product;
param[2] = new SqlParameter("#DESC_PRODUCT", SqlDbType.VarChar, 50);
param[2].Value = Des_Product;
ExecuteCommand("StoredProcedure_name", param);
close_conn();
}
and finally you can call this function
Add_product(Convert.ToInt32(ComboBox.SelectedValue),txt_name.Text,
txt_desc.Text);
if there is any part you don't understand lemme know
I've seen many ways to accomplish this.
One way is to Pipe Delimit your select statement in your stored procedure and then use "Value1|Value2".Split('|')[0] to get Value1.
You could also return a table instead of using multiple parameters
DataTable table = new DataTable();
DataAdapter adapter = new DataAdapter(cmd);
adapter.fill(table);
return table.Rows[0]["Greeting"] + table.Rows[0]["Name"];
In the second example you can return as many 'Parameters' as you want, but you will have to assign them to their rightful spots later in your code.
I've also seen an XML way to do this same feature but I won't provide the code here since I don't personally think it is a very good way to do it. The way I've seen done was adding a bunch of XML attributes to a parent tag, and then coming back later and finding the value of each tag later in the code.
In MYSQL it would go like this
CREATE PROCEDURE O_CAPEREZ.GIO_SP (
#vNOMBRE VARCHAR(50))
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (#vNOMBRE);
select 'Hola' as Greeting, #vNOMBRE as Name
END
Also note what Marc_s commented
You need to set the .Direction of the parameter BEFORE making the call to .ExecuteNonQuery()
From C# Code, I'm trying to call a PACKAGE.PROCEDURE() from Oracle. In this simple example I should get one value from the procedure call, but all I get is error:
wrong number or types of arguments in call to 'RETURN_NUM'
The procedure is declared as follows:
PROCEDURE return_num(xNum OUT NUMBER) AS
BEGIN
xNum:= 50;
dbms_output.put_line('hello world ' || xNum);
END;
C# code:
Oraclecon.Open();
OleDbCommand myCMD = new OleDbCommand("TEST.return_num", Oraclecon);
myCMD.CommandType = CommandType.StoredProcedure;
myCMD.Parameters.Add("xNum", OleDbType.Numeric);
OleDbDataReader myReader;
myReader = myCMD.ExecuteReader();
Can some one please point out what I'm doing wrong. Then in a real scenario I would like to call a procedure that returns a set of values from a custom Type, such as:
TYPE r_interface_data IS RECORD
(
object_id VARCHAR2(16),
obj_type VARCHAR2(32)
);
TYPE t_interfase_data IS TABLE OF r_interface_data;
How can I approach that. Thanks!
UPDATE: In my particular case I ended-up doing the following approach
using (OleDbCommand cmd = new OleDbCommand("PACKAGE.procedure_name"))
{
cmd.CommandType = CommandType.StoredProcedure;
SqlManager sqlManager = new SqlManager();
return sqlManager.GetDataSet(cmd);
}
I don't think you're that far off... try this:
OracleCommand cmd = new OracleCommand("return_num", Oraclecon);
cmd.Parameters.Add(new OracleParameter("xNum", OracleDbType.Decimal,
ParameterDirection.Output));
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
OracleDecimal d = (OracleDecimal)cmd.Parameters[0].Value;
double result = d.ToDouble();
result now contains the out parameter from the procedure.
I think your problem is you were attempting to use a DbDataReader on a stored procedure. DbDataReader is for queries.
Also, I used ODP.net -- that may or may not have contributed to your issue, that you were using Ole.
I have a table called 'MatchType' and it contains:
ID | MatchTypeName
1 | One Day
2 | Two Day
3 | T20
I have a method to retrieve a record from that table based on a sting that will match a value in MatchTypeName:
public static int GetByName(string matchType)
{
MatchType item = new MatchType();
using (SqlConnection con = new SqlConnection(BaseDataAccessLayer.GetConnectionStringByName()))
{
using (SqlCommand cmd = new SqlCommand(STORED_PROC_GetByName, con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#matchTypeName", SqlDbType.VarChar, 20).Value = matchType;
con.Open();
using (IDataReader reader = cmd.ExecuteReader())
{
item.LoadFromReader(reader);
}
}
}
return item.Id;
}
This method calls this stored procedure:
CREATE PROCEDURE [dbo].[MatchType_GetByName]
(#matchTypeName varchar(20))
AS
BEGIN
SET NOCOUNT ON
SELECT
[Id], [MatchTypeName]
FROM
[dbo].[MatchType]
WHERE
[MatchTypeName] = #matchTypeName
RETURN ##ERROR
END
When calling the GetByName method I am passing in a string "One Day". I have confirmed this through debugging. I can't post an error message that is helpful as there isn't one being generated. Just no data is being returned in the reader...
I have a couple of other methods and stored procedures that use a similar process and they work. The only thing that I can see is the difference is that I am using the WHERE clause on a varchar/string value which is something that the other queries don't do...
Yet i can run this stored proc and it returns all the records..
BEGIN
SET NOCOUNT ON
SELECT
[Id],
[MatchTypeName]
FROM
[dbo].[MatchType]
RETURN ##ERROR
END
The default length for varchar declared without size is 1. You declared it like that in your stored proc parameter so you're only passing the first character.
Change your declaration:
(#matchTypeName varchar)
to a relevant size:
(#matchTypeName varchar(20))
Also, add the size in the code and make sure that the case in your parameter name matches your stored proc:
cmd.Parameters.Add("#matchTypeName", SqlDbType.VarChar, 20).Value = matchType;
The procedure is running the query and showing the results (which is why it works in SSMS), but doesn't actually return anything. Try this (note, I haven't actually tested it).
CREATE PROCEDURE [dbo].[MatchType_GetByName]
#matchTypeName varchar(20),
#matchTypeID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
SELECT
#matchTypeID = [Id], [MatchTypeName]
FROM
[dbo].[MatchType]
WHERE
[MatchTypeName] = #matchTypeName
RETURN ##ERROR
END
Try this:
using (SqlCommand cmd = new SqlCommand(STORED_PROC_GetByName, con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#matchTypeName", matchType);
con.Open();
using (IDataReader reader = cmd.ExecuteReader())
{
item.LoadFromReader(reader);
}
}
SqlCommand.Parameters Property