MySQL and C#.Net Stored Procedure and multiple parameter - c#

I am developing (converting application db from MS SQL to MySQL) an application using C#.Net and MySQL. My C# code and stored procedure is working perfect in MS SQL but when trying to ingrate with MySQL getting parameter error. My C# Code is as below and MySQL Stored Procedure is running perfectly (tested in editor using CALL key work and parameter)
public DataTable AlapValidateUser(string email, string password,string Type)
{
DataTable dt = new DataTable();
cmd = new MySqlCommand("UserIdValidation");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = cnn;
string pass = reEncryptpassword(password);
MySqlParameter pramEmail = new MySqlParameter("#v_emailId", email);
pramEmail.Direction = ParameterDirection.Input;
cmd.Parameters.Add(pramEmail);
MySqlParameter pramPassword = new MySqlParameter("#v_password", pass);
pramPassword.Direction = ParameterDirection.Input;
cmd.Parameters.Add(pramPassword);
MySqlDataAdapter adap = new MySqlDataAdapter(cmd);
if (cnn.State != ConnectionState.Open ||
cnn.State == ConnectionState.Broken ||
cnn.State != ConnectionState.Connecting ||
cnn.State != ConnectionState.Executing ||
cnn.State != ConnectionState.Fetching)
cnn.Open();
adap.Fill(dt);
cnn.Close();
return dt;
}
MySQL Stored Procedure is here:
CREATE DEFINER=`root`#`localhost` PROCEDURE `UserIdValidation`(v_emailId NATIONAL VARCHAR(100),v_password
NATIONAL VARCHAR(50))
BEGIN
SELECT UserId ,eMail,BloodGroup
,BloodGroupID,Country AS CountrySlNo ,CountryName ,State ,District
,Location,fName,lName ,DonorType ,LastLogIn ,Validated ,ProfileImage
,MaritalStatus ,Sex ,Height ,Weight ,HealthStatus
,MyFileLocation FROM vwUser WHERE eMail = v_emailId AND
PASSWORD = v_password AND Validated = 'Y';
END$$
During execution exception as below:
Incorrect number of arguments for PROCEDURE alap.UserIdValidation; expected 2, got 1
Can you please help me to find out the error.
UPDATE: My MySQL connector is v.6.6.5. I have checked in debug mode in C# parameter is correct and can see both parameter in command object. Next it is trying to filling Adapter hence this command object is passing to MySQL from Connector and there parameter is missing. I have tried to add same 1st parameter by creating 3rd line then getting error that same parameter already exist.
From this test I am sure it is purely MySQL or mysql connector bug.
I don't know how this bug can exists in such DB where so many people is using mysql.

This is a BUG of MY SQL and I have received solution from MySQL Team. I have implemented this changes in my MySQL Stored Procedure and got solution. MySQL reply as below
Hi Suman,
I have reproduced the issue you described, and exists a workaround that
works perfectly fine and hopefully it will keep you up to speed in your
migration to MySql. The problem here is the NATIONAL usage in the
definition of the parameters for the routine. If you want to define a
particular character set you can define the routine like this:
CREATE DEFINER=`root`#`localhost` PROCEDURE
`UserIdValidation`(v_emailId VARCHAR(100) ***CHARACTER SET utf8***,v_password
VARCHAR(50) CHARACTER SET utf8)
BEGIN
.... rest of code
Or you just can use
CREATE DEFINER=`root`#`localhost` PROCEDURE
`UserIdValidation`(v_emailId VARCHAR(100),v_password VARCHAR(50))
BEGIN
....
The default character set in the server is utf8 and is equivalent to
NATIONAL according to the documentation.
You can check more information here:
http://dev.mysql.com/doc/refman/5.5/en/charset-national.html
Please let me know if the workaround worked for you.

I think you might need to change the way you call the stored proc.
Take a look at this example http://forums.asp.net/t/988462.aspx

Related

How send OUTPUT parameter to MySql stored procedure using FromSqlRaw() in c# entity framework core

In Visual Studio Code C# Project I'm using Microsoft.EntityFrameworkCore 5.0.8 and MySql.EntityFrameworkCore 5.0.5.
I need to call Mysql stored procedure with output parameter using FromSqlRaw() and recive an MySqlException:
"OUT or INOUT argument 2 for routine ID_SP_Clientes_Validar is not a variable or NEW pseudo-variable in BEFORE trigger".
If I use ADO.NET can solve the problem, but i don't want use CommandText
Stored Procedure:
CREATE PROCEDURE `ID_SP_Clientes_Validar`(IN `cliente` decimal(6,0), OUT `mensaje_alta` TINYTEXT)
BEGIN
SELECT * FROM id_clientes WHERE clnumero = cliente;
SET mensaje_alta = 'Cliente Valido.';
END
C# Code:
var arParams = new[] {
new MySqlParameter("#cliente", MySqlDbType.Decimal)
{
Direction = ParameterDirection.Input,
Value = clienteId
},
new MySqlParameter("#mensaje_alta", MySqlDbType.TinyText )
{
Direction = ParameterDirection.Output,
Value = ""
}
};
var cliente = await context.miCliente.FromSqlRaw<ClienteGet>("CALL D_SP_Clientes_Validar(#cliente,#mensaje_alta)",arParams).ToListAsync();
Please help me!!!
Thanks in advance
This is not supported by EF Core when using MySQL.
The underlying issue is that FromSqlRaw uses CommandType.Text but ADO.NET providers for MySQL have no ability to return an output parameter from text commands (MySql.Data bug, MySqlConnector bug), fundamentally due to limitations in the MySQL protocol.
There is more discussion in these issues:
FromSqlRaw() and ParameterDirection.Output - efcore
Parameter direction not supported in CommandType.Text - MySqlConnector

OracleCommandBuilder.DeriveParameters() throws OracleException: ORA-06564: object does not exist

Using the OracleClient that comes with ADO.NET in .NET Framework, I'm trying to call OracleCommandBuilder.DeriveParameters() method on a procedure in the database, but I keep getting an OracleException with the message: ORA-06564: object CustOrdersOrders does not exist, even though I created the procedure successfully. I'm more familiar with SQL Server, so perhaps I'm missing something here.
SQL
file 1:
create or replace PACKAGE PKGENTLIB_ARCHITECTURE
IS
TYPE CURENTLIB_ARCHITECTURE IS REF CURSOR;
END PKGENTLIB_ARCHITECTURE;
/
file 2
CREATE OR REPLACE PROCEDURE "CustOrdersOrders"(VCUSTOMERID IN Orders.CustomerID%TYPE := 1, CUR_OUT OUT PKGENTLIB_ARCHITECTURE.CURENTLIB_ARCHITECTURE)
AS
BEGIN
OPEN cur_OUT FOR
SELECT
OrderID,
OrderDate,
RequiredDate,
ShippedDate
FROM Orders
WHERE CustomerID = vCustomerId;
END;
/
Both these files were executed in SQL*Plus as #"path\to\file1.sql".
Code
This is using the Enterprise Library Data Access Application Block, which ultimately wraps the ADO.NET API.
DatabaseProviderFactory factory = new DatabaseProviderFactory(...); //this gets a custom configuration source
Database db = factory.Create("OracleTest");
DbCommand storedProcedure = db.GetStoredProcCommand("CustOrdersOrders");
DbConnection connection = db.CreateConnection();
connection.Open();
storedProcedure.Connection = connection;
db.DiscoverParameters(storedProcedure); //this ultimately calls OracleCommandBuilder.DeriveParameters(), which throws the exception.
When I run direct SQL queries using the same connection, they succeed.
More Details
This is actually part of unit tests written for the Data Access Application Block, which I forked here in an attempt to revive this library. That's why it's using the System.Data.OracleClient and not the ODP.NET. The entire set of tests at https://github.com/tsahi/data-access-application-block/blob/master/source/Tests/Oracle.Tests.VSTS/OracleParameterDiscoveryFixture.cs breaks in a similar way.
The tests are running on an Oracle Database XE I installed locally.
Update
Following question by #madreflection, yes, the following code runs correctly:
Database db = DatabaseFactory.CreateDatabase("OracleTest");
string spName = "AddCountry";
DbCommand dbCommand = db.GetStoredProcCommand(spName);
db.AddInParameter(dbCommand, "vCountryCode", DbType.String);
db.AddInParameter(dbCommand, "vCountryName", DbType.String);
db.SetParameterValue(dbCommand, "vCountryCode", "UK");
db.SetParameterValue(dbCommand, "vCountryName", "United Kingdom");
db.ExecuteNonQuery(dbCommand);
using (DataSet ds = db.ExecuteDataSet(CommandType.Text, "select * from Country where CountryCode='UK'"))
{
Assert.IsTrue(1 == ds.Tables[0].Rows.Count);
Assert.AreEqual("United Kingdom", ds.Tables[0].Rows[0]["CountryName"].ToString().Trim());
}
where "AddCountry" is defined as
CREATE OR REPLACE PROCEDURE ADDCOUNTRY
(vCountryCode IN Country.CountryCode%TYPE,
vCountryName IN Country.CountryName%TYPE
)
AS
BEGIN
INSERT INTO Country (CountryCode,CountryName)
VALUES (vCountryCode,vCountryName);
END;
/
It's interesting to note, though, that in this case the OracleDatabase pointed by db has in it's packages list just EntlibTest, defined (if I understand correctly) by
CREATE OR REPLACE PACKAGE EntlibTest AS
PROCEDURE GetProductDetailsById
(vProductID IN NUMBER,vProductName OUT VARCHAR2,vUnitPrice OUT NUMBER);
END EntlibTest;
/
and then there is another file defining the body of this procedure with
CREATE OR REPLACE PACKAGE BODY EntlibTest AS
PROCEDURE GetProductDetailsById
(vProductID IN NUMBER,vProductName OUT VARCHAR2,vUnitPrice OUT NUMBER)
AS
BEGIN
SELECT ProductName,UnitPrice INTO vProductName,vUnitPrice FROM Products where ProductId = vProductId;
END;
END EntlibTest;
/

Target database schema could not be retrieved - Visual Studio Error

I am new to programming in Visual Studio C#. I have been trying to create a table using a Stored Procedure. When I try to update the table, I get an error.
The Stored Procedure script is as follows:
CREATE TABLE [dbo].[Table]
(
[Id] INT NOT NULL PRIMARY KEY,
[Error] VARCHAR(30) NULL
)
GO
CREATE PROCEDURE [dbo].[InsertLog]
(
#error varchar(30)
)
AS
INSERT INTO [dbo].[Table]
(
[Error]
)
VALUES
(
#error
)
GO
My connection string is as follows:
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Database1.mdf;Persist Security Info=true;Integrated Security=True;"
The error I get when updating the table is as follows:
I am using the LocalDB and I have no login credentials. Kindly help me with the error.
Note: I also went through other StackOverflow questions and none helped.
Thanks
I think you can refer to the following steps to execute the stored procedure.
First, you can create table like the following picture. Here I want to mention that you
need to use automatic increment if you want to use the stored procedure you provided.
Also, you can not create stored procedure here.
Second, click database->choose Programmability->choose stored procedures-> right click Add new procedure like the following:
CREATE PROCEDURE [dbo].[InsertLog]
(
#error varchar(30)
)
AS
INSERT INTO [dbo].[Newtable]
(
[Error]
)
VALUES
(
#error
)
Finally, you can use the following code to call stored procedure in c#.
string connectionstring = #"Connectionstring";
SqlConnection connection = new SqlConnection(connectionstring);
connection.Open();
SqlCommand command = new SqlCommand("InsertLog",connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#error", textBox1.Text);
command.ExecuteNonQuery();
connection.Close();
How have you mentioned your connection string? COuld you please add that as well

get next sequence value Oracle using Ado.Net c#

I have tried various forms of the following method to get the next sequence value from an Oracle DB in my asp.net app. The sql statement works fine in Toad (11g). The sql statement includes "Select ... myschema.mySeq.nextval ... from dual. But the error I receive when I get to cmd.ExecuteNonQuery() -- the error is:
>
Exception Details: Oracle.DataAccess.Client.OracleException: ORA-00942: table or view does not exist
<<
Authentication is a very big deal at the place where I am at. Is this a data Access problem or is something incorrect with my method (below)? If something is incorrect with the code below what is the correction I need to make? Note: the app (big app) has hundreds of calls to SPs (which all work fine), so I basically copied the connection string code and used a constant (like they do throughout the app). If I use an SP this works, but I want to not use an SP just straight forward Ado.Net. What is the fix?
public int getNextPositionSequence(string userSeq)
{
OracleConnection conn = new OracleConnection(DaoHelper.GetConnectionString("AuthenticatedOracleConnectionString"));
conn.Open();
conn.ClientId = userSeq;
string sql = "SELECT ddtms.position_seq.nextval from dual";
OracleCommand cmd = new OracleCommand(sql, conn);
object s = cmd.ExecuteNonQuery(); //<<<--- crashes here
conn.Close();
return 1;
}

Parameter '#s' must be defined

I'm having problems to run a script inside a custom action. The script creates and sets up a database in a localhost MySQL server.
Concretely, I have problems with one of my procedures:
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `UpdateAutoInc`(IN `increment` BIGINT)
BEGIN
SET #s = concat('ALTER TABLE tblactionservices AUTO_INCREMENT ',increment);
PREPARE stmt FROM #s;
EXECUTE stmt;
SET #s = concat('ALTER TABLE tblbannedclient AUTO_INCREMENT ',increment);
PREPARE stmt FROM #s;
EXECUTE stmt;
END$$
DELIMITER ;
In the script, before this procedure, I have 2 other procedures that run perfectly.
The error I get when I install the application is "Parameter '#s' must be defined". Looking for the Internet I found this blog but I added the "Allow User Variables=True;" with no luck. With this piece of text, the script crashes directly on the first procedure. Indeed, it crashes always, no matter what it finds (procedures, tables...). The error I get is absolutely useless "You have an error in your SQL Syntax; check the manual bla bla", so I can't find the problem.
This is the class I'm using to run the script from c#:
private void ExecuteSql(string DatabaseName, string Sql)
{
MySqlConnection connection = new MySqlConnection { ConnectionString = "server=127.0.0.1;User Id=root" };
MySqlCommand command = new MySqlCommand(Sql, connection);
command.Connection.Close();
command.Connection.Open();
try
{
command.ExecuteNonQuery();
}
finally
{
// Closing the connection should be done in a Finally block
command.Connection.Close();
}
}
The script wasn't manually typed but it was automatically generated from PhPMyAdmin. The version of MySQL server is 5.5 and the connector version is 6.5.5.0

Categories

Resources