Reputation: 691
I have parameterized stored procedure (tested and works) in mysql. I wanted to replace my long select statement with stored procedure in my code. With select statement it worked but now I am not able to run it with sp (commented string req).
My stored procedure:
CREATE DEFINER=`root`@`%` PROCEDURE `GetProjectVM`(
IN projectName NVARCHAR(255)
)
BEGIN
select VirtualMachines.Name,
VirtualMachines.IpAddress,
VirtualMachines.DiskSize,
VirtualMachines.CPU,
VirtualMachines.Ram,
VirtualMachines.ImageUrl,
VirtualMachines.Role,
Hypervisors.Name as Hypervisor,
Managements.Netmask,
Managements.Gateway from VirtualMachines inner join Projects
on Projects.id = VirtualMachines.ProjectId inner join Hypervisors
on Hypervisors.HypervisorId = VirtualMachines.HypervisorId inner join Managements
on VirtualMachines.ManagementId = Managements.Id
where Projects.Name = projectName;
END
My code looks like:
private string _dbUrl;
private MySqlConnection _cnn;
public Dbmanagement(string dbUrl)
{
this._dbUrl = dbUrl;
this._cnn = new MySqlConnection(this._dbUrl);
}
private MySqlDataReader ExecuteMysqlCommand(string cmd)
{
_cnn.Open();
var result = new MySqlCommand(cmd, _cnn);
return result.ExecuteReader();
}
public IEnumerable<VM> GetProjectVM(string projectName)
{
var vmList = new List<VM>();
//string req =
// $"select VirtualMachines.Name,VirtualMachines.IpAddress,VirtualMachines.DiskSize,VirtualMachines.CPU,VirtualMachines.Ram,VirtualMachines.ImageUrl,VirtualMachines.Role,Hypervisors.Name as Hypervisor,Managements.Netmask,Managements.Gateway from VirtualMachines inner join Projects on Projects.id = VirtualMachines.ProjectId inner join Hypervisors on Hypervisors.HypervisorId = VirtualMachines.HypervisorId inner join Managements on VirtualMachines.ManagementId = Managements.Id where Projects.Name = \"{projectName}\" ;";
MySqlCommand cmd = new MySqlCommand("GetProjectVM", _cnn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@projectName", projectName);
var req = cmd;
var rd = ExecuteMysqlCommand(req.ToString());
while (rd.Read())
{
vmList.Add(new VM(rd));
}
_cnn.Close();
return vmList;
}
Upvotes: 0
Views: 172
Reputation: 1500055
The problem - or at least the first problem - is how you're executing the command.
Calling ToString
on a MySqlCommand
is very unlikely to be able to convey all the relevant information. You're losing parameterization, command type etc.
Change this:
var req = cmd;
var rd = ExecuteMysqlCommand(req.ToString());
to
_cnn.Open();
var rd = req.ExecuteReader();
I'd also suggest not having a single MySqlConnection
, but just constructing one when you need to, and letting the connection pool manage making that efficient. So something like:
using (var connection = new MySqlConnection(_dbUrl))
{
connection.Open();
using (var cmd = new MySqlCommand("GetProjectVM", connection))
{
cmd.CommandType = CommandType.StoredProcedure;
// Avoid AddWithValue where possible, to avoid conversion issues.
cmd.Parameters.Add("@projectName", MySqlDbType. VarChar).Value = projectName;
using (var reader = cmd.ExecuteReader())
{
var list = new List<VM>();
while (reader.Read())
{
list.Add(new VM(reader));
}
return list;
}
}
}
Upvotes: 3