turn c# code into mysql function - mysql

I have the following code in C# that I would like to turn into a MySQL snippet instead?
foreach (DataRow row in dtBills.Rows)
{
classes.UtilityBill ub = new classes.UtilityBill(row);
if (ub.ApprovedBy > 0)
{
if (ub.RemainingBalance() > 0) { totalOutstanding += ub.RemainingBalance(); numberOfUnpaidBills++; }
if (ub.RemainingBalance() > 0 && ub.IsOverDue()) { numberOfOverdueBills++; }
}
else
{
if (ub.ApprovedBy == 0)
{
awaitingApproval++;
}
else
{
rejectedBills++;
}
}
}
ub.RemainingBlaance() basically checks two fields in the table and subtracts, amount_due - amount_paid
What I'm looking to have returned is a single row that looks something like:
totalOutstanding, numberOfUnpaidBills, numberOfOverdueBills, awaitingApproval, rejectedBills
Original table:
I know that this might come across like a lazy question, but I have never dealt with coding in mysql, just simple queries, and I have no idea on how to start. A push in the right direction would suffice, not a complete solution.
Thanks!

To query mysql you can use the mysql.data nuget package. You can look up their documentation. I created a nuget to simplify code from any c# framework to mysql as well. If you don't mind third party nugets, you can try it out. It is called mysql.simple. From what I understand from what the code is trying to do, here is a small code for pulling data:
using (Database db = ConnectionString) // initializes connection
{
// you can omit the below select function if you would like to select all
using (var Row = db.Select("unit_cost, start_reading")
From("tblName").Query()
while(Row.Read()){ // gets each row
ub.unit_cost = Row["unit_cost"];
ub.start_reading= Row["start_reading"];
.
.
.
}
}
The db object above has select, update and insert functions with all variations including insert statements with selects. However if you would like to use raw sql queries, you can directly use db.Query("sql query here"). You can see more documentations here http://mysqlsimple.azurewebsites.net/docs
Here is a sample mySql stored procedure I had with me:
DELIMITER //
DROP PROCEDURE IF EXISTS proc_IF;
CREATE PROCEDURE proc_IF (IN param1 INT)
BEGIN
DECLARE variable1 INT;
SET variable1 = param1 + 1;
IF variable1 = 0 THEN
SELECT variable1;
END IF;
IF param1 = 0 THEN
SELECT 'Parameter value = 0' ;
ELSE
SELECT 'Parameter value <> 0' ;
END IF;
END //
This example contains parameters, variables and if statement examples.
You can call this in c# something like this:
db.QueryValue("CALL proc_IF (#0)", myVal);

Related

ExecuteSqlCommand return -1?

I am trying to call a stored procedure from code , in ef core 2 i found that i can use context.database.ExecuteSqlCommand() function to execute any stored procedure in my database.
While the stored procedure works fine in my sql server instance :
calling it from my code , returns -1 result !?:
using (var context = new AZPDBDEMOGZContext(optionsBuilder.Options))
{
var existUser = context.Database.ExecuteSqlCommand("GetIdUsager_ByNomPrenomEmail #p0,#p1,#p2", parameters:new[] { "rouarouarouarouaroua", "wiem", "test#gmail.com" });
}
what m i doping wrong ?
ExecuteSqlCommand will only return a 'rows affected' integer for a DML query aka insert/update/delete. Your stored proc looks like its returning a result set so it returns -1 as you've not provided a statement that changes the data source. You'll need to create a POCO and use FromSql to populate it.

Binding values to stored procedure with MySQL > 5 and QSqlQuery?

I just want to run this type of procedure from Qt side:
DROP PROCEDURE IF EXISTS get_patient_info_brief;
DELIMITER //
CREATE PROCEDURE get_patient_info_brief(IN _id int)
BEGIN
SELECT age, height, weight, sessions, remaining_sessions, `description` FROM patient_info WHERE `id` = _id;
END //
DELIMITER ;
like this:
const auto q1 = QString("CALL get_patient_info_brief(?);");
const auto q2 = QStringLiteral("SELECT age, height, weight, sessions, remaining_sessions, `description` FROM patient_info WHERE `id` = ?;");
auto db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("mydb");
db.setUserName("root");
db.setPassword("pswd");
if (db.open()) {
QSqlQuery q(db);
q.prepare(q2);
q.addBindValue(QVariant(1));
if (q.exec()) {
qDebug() << "query executed";
if (q.size()) {
while (q.next()) {
qDebug() << q.record();
}
}
}
}
if I use the q2 the result will be returned back but it's not true with q1
Docs would say:
MySQL 5 introduces stored procedure support at the SQL level, but no API to
control IN, OUT, and INOUT parameters. Therefore, parameters have to
be set and read using SQL commands instead of QSqlQuery::bindValue().
How can we get manage to do the job with q1 one?
I'm using Qt5.8 + MySQL 8.0.17 + MySQL Connector C 6.1
Using PyQt5 there are two ways to call the stored procedure in PyQt5 and both
work. I guess these will also work in Qt even though I haven't tried it.
q.exec("CALL get_patient_info-brief ({})".format(1)
or
q.prepare("CALL get_patient_info-brief (:id)")
q.bindValue(":id", 1)
q.exec()
Both work pretty well for me. I understand that when using positional
placeholders using named
placeholders it's preferable.

Stored Procedure call not working Entrity Framework 5 code first

I have a stored procedure in my database:
ALTER PROCEDURE [dbo].[DeletePaySlip]
#PayRunId BIGINT,
#EmployeeId BIGINT
AS
BEGIN
DECLARE #PaySlipId BIGINT
BEGIN TRY
SELECT #PaySlipId = Id
FROM PYREmployeePaySlip
WHERE PayRunId = #PayRunId AND EmployeeId = #EmployeeId
BEGIN TRANSACTION t1
IF #PaySlipId IS NOT NULL
BEGIN
DELETE FROM PYREmployeePaySlipDetail WHERE PaySlipId = #PaySlipId
DELETE FROM PYREmployeePaySlip WHERE Id = #PaySlipId
END
COMMIT TRANSACTION t1
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION t1
END CATCH;
END
If I execute the stored procedure from SQL query window, it works.
Now I am trying to call the stored procedure from C# code
public bool DeleteEmployeePaySlip(long payRunId, long employeeId)
{
bool success = true;
var sqlparamPayRunId = new SqlParameter("#PayRunId", payRunId);
var sqlparamEmployeeId = new SqlParameter("#EmployeeId", employeeId);
using (var dbContext = new CRMDbContext())
{
try
{
var res = dbContext.Database.SqlQuery<Object>("EXEC DeletePaySlip #PayRunId, #EmployeeId",
sqlparamPayRunId,
sqlparamEmployeeId);
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
foreach (var ve in eve.ValidationErrors)
{
}
}
throw;
}
}
return success;
}
When I call the method above, it does not throw any error. But the stored procedure not seems to be called.
According to the documentation, the expression
dbContext.Database.SqlQuery<Object>("EXEC DeletePaySlip #PayRunId, #EmployeeId",
sqlparamPayRunId,
sqlparamEmployeeId);
... will "[c]reate a raw SQL query that will return elements of the given generic type".
So what it returns (your object res) will be of this type:
DbRawSqlQuery<object>
This isn't (yet) the results of the query: it's more like an encapsulation of a query. You won't get the results (and, most importantly from your point of view, the SQL won't execute) until you enumerate it.
But actually, it looks to me like you're using the wrong method to execute your stored procedure. It's not a query at all, but a data manipulation. So try this instead:
dbContext.Database.ExecuteSqlCommand("EXEC DeletePaySlip #PayRunId, #EmployeeId",
sqlparamPayRunId,
sqlparamEmployeeId);
Look here for more details.

mysql procedure how to execute a query that retrieves data within a loop then return a custom value

I don't understand how procedures work even though I search for several topic/tutorial but only found pointless examples.
In PHP my code would look like this:
function getFullPathFromID($ID)
{
$path = '';
while($result = $c->query("SELECT IDParentFolder,path FROM folders WHERE ID=$ID")->fetch())
{
$ID = $result->IDParentFolder;
$path = $result->path.'/'.$path;
}
return $path;
}
I couldn't get it working with procedures, I can't even make a query to the db:
DELIMITER #
CREATE PROCEDURE getFullPathFromID(ID INT)
BEGIN
SELECT path FROM folders WHERE ID = ID;
END
#
When I execute it with a valid value I still get "MySQL returned an empty result set (i.e. zero rows)."
So how can I execute a query that retrieves data within a loop and then return a custom value (concatenation of each step's value)?
Thanks
You have a problem in your stored procedure because the scalar id has the same name as a column in the table. So, the expression:
where id = id
does not do what you expect.
You should write this as:
DELIMITER #
CREATE PROCEDURE getFullPathFromID(v_ID INT)
BEGIN
SELECT path FROM folders f WHERE f.ID = v_ID;
END
#
However, I'm not sure this will fix the problem of no rows being selected.
I finally got it working.
BEGIN
DECLARE v_IDParentFolder INT;
DECLARE v_Name VARCHAR(255);
SET path='';
REPEAT
SELECT IDParentFolder,Name INTO v_IDParentFolder, v_Name FROM folders WHERE ID = IDFolder;
SET IDFolder = v_IDParentFolder;
SET path = CONCAT(v_Name,'/',path);
UNTIL v_IDParentFolder IS null END REPEAT;
SET path = CONCAT('/',path);
END
For the "SELECT path FROM folders" I mistook 'path' for 'name' so I couldn't get any result indeed...
For the others beginners in SQL and especially procedures, a SELECT query will not save the result but return it, in order to only save the result "INTO" has to be used as in my code and these variables have to be declared at the beginning of the procedure.
Thanks to the guy who downvoted me, he has been really helpful.
Your code is wrong, using mysqli extension you should prepare to avoid sql injection.
You should not put the query into a loop, you would loop through a recordset, but in your case you are getting a single row so it makes no sense. here 's what you should really do:
$query = 'SELECT path FROM folders WHERE ID = ?';
$stmt = $mysqli->prepare($query);
$stmt->bind_param('i', $id);
if ($stmt->execute()){
$row = $stmt->fetch_assoc();
$path = $row['path'];
}
return $path;

Retrieve a value inside a stored procedure and use it inside that stored procedure

delimiter //
CREATE DEFINER=root#localhost PROCEDUREgetData(IN templateName VARCHAR(45),IN templateVersion VARCHAR(45),IN userId VARCHAR(45))
BEGIN
set #version = CONCAT("SELECT saveOEMsData_answersVersion FROMsaveOEMsData WHERE saveOEMsData_templateName = '",templateName,"' ANDsaveOEMsData_templateVersion = ",templateVersion," AND saveOEMsData_userId= ",userId);
PREPARE s1 from #version;
EXECUTE S1;
END // delimiter ;
I am retrieving saveOEMsData_answersVersion, but I have to use it in an IF loop, as in if the version == 1, then I would use a query, else I would use something else. But I am not able to use the version. Could someone help with this?? I am only able to print but not able to use the version for data manipulation. The procedure works fine but I am unable to proceed to next step which is the if condition.
The if condition would have something like the below mentioned.
IF(ver == 1) THEN SELECT "1";
END IF;
IF is allowed inside a Procedure, you can not use IF inside SQL, in SQL you can use CASE, but that doesn't have the same abilities.
Build a second procedure to handle the IF/Then for the results of getData