recuperar - Pedir ejemplo legítimo de llamar al procedimiento almacenado C#: MYSQL
procedimientos almacenados sql yc (2)
He pasado aproximadamente 7 horas tratando de resolver esto por prueba y error. Todos los ejemplos en línea que he visto no funcionan, o no se aplican, o solo muestran la mitad de lo que estoy buscando.
Esto es lo que estoy pidiendo: 1. Un ejemplo de un procedimiento almacenado simple en MYSQL usando un parámetro IN y un parámetro OUT. 2. Un ejemplo de un FUNCIONAMIENTO (realmente importante, porque los ejemplos en línea no han funcionado algunas veces ...) se llama desde Visual Studio, usando C #. O bien funciona una llamada de texto o un tipo de comando de procedimiento almacenado. 3. AddWithValue ha quedado en desuso. 4. Me encantaría ver que el parámetro out funcione realmente.
Si esto es imposible con MYSQL y Visual Studio, sería bueno saberlo también.
La documentación de MYSQL no es lo suficientemente detallada para este ejemplo en particular. Y por favor, no odio Visual Studio o C #.
¡Gracias por adelantado! :)
EDITAR:
¡Esto es lo que he logrado hacer hasta ahora, y NO FUNCIONA!
Lado MYSQL, usando HeidiSQL:
CREATE DEFINER=`root`@`localhost` PROCEDURE `login`(IN `stuff` VARCHAR(50), IN `pass` VARCHAR(50), OUT `param3` INT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''''
BEGIN
set param3 = 0;
set param3 = (select count(*) from users where username=stuff and userpassword=pass);
select @param3;
END
Y en el lado C #, intento obtener este parámetro OUT. Ahora, esto es después de múltiples iteraciones, donde he destruido lo que solía ser la función, y lo resumí en dos cuestiones: 1. Los parámetros OUT no funcionarán, y 2. Aunque Visual Studio pasa los parámetros IN, SQL se niega. para reconocerlos.
protected void Login_Authenticate(object sender, AuthenticateEventArgs e)
{
using (MySqlConnection con = new MySqlConnection(strcon))
{
con.Open();
MySqlCommand com = new MySqlCommand("CALL login(@stuff, @pass, @param3);", con);
com.CommandType = CommandType.Text;
com.Parameters.Add("@stuff", MySqlDbType.VarChar);
com.Parameters["@stuff"].Value = Login.UserName;
com.Parameters.Add("@pass", MySqlDbType.VarChar);
com.Parameters["@pass"].Value = Login.Password;
try
{
obj = com.ExecuteScalar();
objparam = com.Parameters["param3"].Value;
if (Convert.ToInt32(obj) != 0)
{
Response.Redirect("Welcome.aspx");
}
else
{
Login.PasswordRequiredErrorMessage = "invalid user name and password";
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
con.Close();
}
}
Creo que el código y las imágenes dicen más que nunca.
C # DB Layer (DB Layer tiene conn
como una cadena de conexión):
// Note: this is an instance (myDB in terms of the GUI Object)
using System.Data;
using MySql.Data.MySqlClient;
...
...
public long MultBySeven(long theNum)
{ // Call a Mysql Stored Proc named "multBy7"
// which takes an IN parameter, Out parameter (the names are important. Match them)
// Multiply the IN by 7 and return the product thru the OUT parameter
long lParam = 0;
using (MySqlConnection lconn = new MySqlConnection(connString))
{
lconn.Open();
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = lconn;
cmd.CommandText = "multBy7"; // The name of the Stored Proc
cmd.CommandType = CommandType.StoredProcedure; // It is a Stored Proc
// Two parameters below. An IN and an OUT (myNum and theProduct, respectively)
cmd.Parameters.AddWithValue("@myNum", theNum); // lazy, not specifying ParameterDirection.Input;
cmd.Parameters.AddWithValue("@theProduct", MySqlDbType.Int32);
cmd.Parameters["@theProduct"].Direction = ParameterDirection.Output; // from System.Data
cmd.ExecuteNonQuery(); // let it rip
Object obj = cmd.Parameters["@theProduct"].Value;
lParam = (Int32)obj; // more useful datatype
}
}
return (lParam);
}
Capa de prueba GUI de C #:
private void btnTestInOut_Click(object sender, EventArgs e)
{ // This GUI Layer call thru the use of a business object or data layer object (`myDB`)
long localHere = myDB.MultBySeven(11);
}
Procedimiento almacenado (tome un número, multiplique por 7):
DROP PROCEDURE IF EXISTS multBy7;
DELIMITER $
CREATE PROCEDURE multBy7
( IN myNum INT,
OUT theProduct INT
)
BEGIN
SET theProduct=myNum*7;
END$
DELIMITER ;
Vista de depuración (léase: funciona. 11x7 = 77):
MySQL Connector 6.9.9.0
/ Visual Studio 2015
:
Consulte también 5.10.1 Uso de rutinas almacenadas desde el conector / red , edad desconocida.
Debe configurar una referencia al parámetro
var param3 = new MySqlParameter();
param3.Direction = ParameterDirection.Output;
param3.DbType = // whatever the dbtype for int is or whatever you need.
param3.ParameterName = "param3";
com.Parameters.Add(param3);
en tu bloque try, inserta
var result = com.ExecuteReader(); // or com.ExecuteScalar();
después de ejecutar eso, su parámetro debería tener el valor completado y también debería poder leer los resultados del SP (seleccionar).
var paramResult = param3.Value;
La lectura de los resultados del SP se puede realizar como lector o escalar.
// execute reader
while (result.Read()) {
int value = result.GetInt32(0));
} /* read returned values in result */
// execute scalar
int value;
if (int.TryParse($"{result}", out value)) {
/* do something with value */
}
/ ************************************************ /
Este bloque debería llevarte a donde necesitas ir
const string strcon = "whatevs";
using (MySqlConnection con = new MySqlConnection(strcon))
{
const string sql = "login";
MySqlCommand com = new MySqlCommand(sql, con);
com.CommandType = CommandType.StoredProcedure;
var stuffParam = new MySqlParameter("stuff", stuffValue);
var passParam = new MySqlParameter("pass", passValue);
var param3Param = new MySqlParameter();
param3Param.ParameterName = "param3";
param3Param.DbType = DbType.Int32;
param3Param.Direction = ParameterDirection.Output;
com.Parameters.Add(stuffParam);
com.Parameters.Add(passParam);
com.Parameters.Add(param3Param);
try
{
var scalarResult = com.ExecuteScalar();
// because you used select @param3 in your sp.
int value;
if (int.TryParse($"{scalarResult}", out value))
{
//do something with value
}
//// because you used select @param3 in your sp.
//var readerResult = com.ExecuteReader();
//if (readerResult.Read())
//{
// //
// value = readerResult.GetInt32(0);
//}
int param3Returned;
if(int.TryParse($"{param3Param.Value}", out param3Returned))
{
// do something with param3Returned
}
}
catch (Exception ex)
{
// do something with ex
}
}