How to create and call MySQL stores procedures? - php

The table[file_request ] structure:
user_id[INT] file_id[CHAR(10)] all_files
This is the SQL code which work fine in MySQL clien: I am using heidisql
DROP PROCEDURE IF EXISTS check_user_files;
DELIMITER \\
CREATE PROCEDURE check_user_files(IN p_user_id INT,IN p_file_id CHAR(10),IN p_all_files VARCHAR(500))
BEGIN
IF EXISTS(SELECT 1 FROM file_request WHERE user_id = p_user_id AND movie_id = p_file_id) THEN
UPDATE file_request SET `requring_date`=NOW(),`all_files`= p_all_files WHERE `user_id`=p_user_id AND `movie_id`=p_file_id;
ELSE
INSERT INTO file_request (`user_id`,`requring_date`,`movie_id`,`all_files`)
VALUES (p_user_id,NOW(),p_file_id,p_all_files);
END IF;
END \\
DELIMITER ;
CALL check_user_files('23','T40431284','07 08 10 11 13 14');
DELIMITER ;
CALL check_user_files('23','F87951','01 02 03');
And I trying to create and execute the SQL query from PHP [didn't work] :
// create the call procedure statements
foreach($fileData as $key=>$value){
$callSP .= "DELIMITER ; \n
CALL check_user_files('$userID','$key','$value');\n";
}
$insert_file_request_query = "DROP PROCEDURE IF EXISTS check_user_files;
DELIMITER \\\\
CREATE PROCEDURE check_user_files(IN p_user_id INT,IN p_file_id CHAR(10),IN p_all_files VARCHAR(500))
BEGIN
IF EXISTS(SELECT 1 FROM file_request WHERE user_id = p_user_id AND movie_id = p_file_id) THEN
UPDATE file_request SET `requring_date`=NOW(),`all_files`= p_all_files WHERE `user_id`=p_user_id AND `movie_id`=p_file_id;
ELSE
INSERT INTO file_request (`user_id`,`requring_date`,`movie_id`,`all_files`)
VALUES (p_user_id,NOW(),p_file_id,p_all_files);
END IF;
END \\\\
$callSP";
mysqli_query($conn,$insert_file_request_query);
The SQL query which created from PHP didn't work as in the MySQL client!?
So, how can I fix it!?
[update1]
I found that the SQL query must in the special format [ the formate which work fine in the MySQL client] or shouldn't work,I tried to copy and paste the query which echo from the PHP, the query code become one line and couldn't execute in MySQL client,too.
[update2]
The code of create store procedure will work fine when I execute it alone from PHP.I mean,I split the whole process into three parts and execute them one by one.
part1: drop the procedure if it was exists; [using mysqli_query()]
part2: create the procedure;[using mysqli_query()]
part3:call the procedure;[using mysqli_multi_query()]
$insert_file_request_query = '';
foreach($fileData as $key=>$value){
$insert_file_request_query .= "CALL check_save_file_request('$userID','$key','$value');";
}
mysqli_multi_query($conn,$insert_file_request_query);
And my final solution was to create the Store Procedure in MySQL and call it from the PHP.It works fine now.
Thank you very much!!

You can't combine multiple statements in mysqli_query. Split out the definition of the stored procedure from the CALLs to it. If that still fails, we'll need the full and exact error message that you receive.

Related

How to pass an array to SQL Server using PHP

Good day,
If I have the following code in SQL Server:
CREATE TYPE PartList
AS TABLE
(
PartID varchar(30),
Quantity int
);
GO
CREATE PROC spInsertPartList
#List AS PartList READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO Part (PartID, Quantity)
VALUES (SELECT PartID, Quantity FROM #List)
END
GO
Can I now call this procedure from PHP stating something like the following:
$array = array('PartNr123' => 50, 'PartNr25' => 4);
$stmt = mssql_init('spInsertPartList');
mssql_bind($stmt,'#List', &$array, PartList, false, false);
mssql_execute($stmt);
I found the code for the SQL statements here, but unfortunately the code example works with C# DataTable.
EDIT:
Furthermore I am getting the following errors when executing the SQL script:
Msg 2715, Level 16, State 3, Procedure InsertStockTake, Line 194
Column, parameter, or variable #1: Cannot find data type dbo.CallPartList
And also this:
Msg 1087, Level 16, State 1, Procedure InsertStockTake, Line 200
Must declare the table variable "#partList".
Which is caused by the following code:
CREATE PROC dbo.InsertStockTake
#partList AS dbo.CallPartList READONLY
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
DECLARE #partNr varchar(15), #qtyCount smallint, #qtyDB smallint
DECLARE curStock CURSOR FOR (SELECT PartNr, Qty FROM #partList)
OPEN curStock
FETCH NEXT FROM curCallPart INTO #partNr, #qtyCount
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #qtyDB = StockOH FROM dbo.Stock WHERE PartNr =
#partNr
INSERT INTO scArchive.StockLevel(PartNr,
StockOHDatabase, StockOHCounted, DateCaptured)
VALUES (#partNr, #qtyDB, #qtyCount, GETDATE())
FETCH NEXT FROM curCallPart INTO #partNr, #qtyCount
END
CLOSE curStock
DEALLOCATE curStock
COMMIT
END TRY
BEGIN CATCH
THROW;
ROLLBACK
END CATCH
END
GO
Thank you in advance
No needed for this question any more. I used mysqli_* in php and adjusted my table structure and moved to MySQL rather than MS SQL

Query works with mysql but doesn't work with php sql call

I have a products table stored inside the database which contains info related to the product.I have a stored procedure that gets the rows with maximum quantity.
Whenever i try to call that stored procedure from the php it returns false while when i run the same query in mysql console, it returns me the rows.
PHP Code:
$resVal=$mysqli->query('CALL get_max_quant_rows("'.$company.'","'.$type.'","'.$limit.'")');
$countVal=$resVal->fetch_row();
$countVal=$countVal[0];
$results = $mysqli->query('CALL get_max_quant_rows("'.$company.'","'.$type.'","'.$limit.'")');
var_dump('CALL get_max_quant_rows("'.$company.'","'.$type.'","'.$limit.'")');
var_dump($results);
The ouput of the var_dump of the above queries give me:
string(72) "CALL get_max_quant_rows("1471941595186287666657bc0bdb1c25d","Cakes","1")" bool(false)
I have shown you the var_dump of the query as to show you that the values are going perfectly inside the stored procedure.
When i ran the same query inside the console,it ran and it gave me the results.What could pe the possible reason for this behaviour?
Stored Procedure:
DELIMITER $$
USE `dboxyz`$$
DROP PROCEDURE IF EXISTS `get_max_quant_rows`$$
CREATE PROCEDURE `get_max_quant_rows`(company VARCHAR(8000),product_type VARCHAR(8000),limiter INT)
BEGIN
DECLARE emptyCheckFirst BIT;
DECLARE emptyCheckSecond BIT;
SET emptyCheckFirst=`dboxyz`.isNullOrEmpty(company);
SET emptyCheckSecond=`dboxyz`.isNullOrEmpty(product_type);
IF (emptyCheckFirst=0 AND emptyCheckSecond=0)
THEN
SELECT p1.id,p1.price,p1.product_code,p1.product_name,p1.quantity,p1.amount,p1.companyId FROM products p1
INNER JOIN (SELECT product_code,MAX(quantity) max_quantity FROM products WHERE companyId=company AND `type`=product_type
GROUP BY product_code) p2 ON p1.product_code=p2.product_code AND p1.quantity=p2.max_quantity LIMIT limiter;
END IF;
IF emptyCheckFirst=1 AND emptyCheckSecond=1
THEN
SELECT p1.id,p1.price,p1.product_code,p1.product_name,p1.quantity,p1.amount,p1.companyId FROM products p1
INNER JOIN (SELECT product_code,MAX(quantity) max_quantity FROM products
GROUP BY product_code) p2 ON p1.product_code=p2.product_code AND p1.quantity=p2.max_quantity LIMIT limiter;
END IF;
END$$
DELIMITER ;
Update:
Error given by the DB
Commands out of sync; you can't run this command now
DELIMITER $$
USE `dboxyz`$$
DROP FUNCTION IF EXISTS `isNullOrEmpty`$$
CREATE FUNCTION `isNullOrEmpty`(xx VARCHAR(8000)) RETURNS BIT(1)
BEGIN
DECLARE somevariable VARCHAR(8000);
SET somevariable=xx;
IF (somevariable IS NOT NULL AND LEN(somevariable)>0)
THEN
RETURN 0;
ELSE
RETURN 1;
END IF;
END$$
DELIMITER ;
MySQL stored procedures can return more than one result set, that is the reason to clear all results before do another query using the same connection.
Just use next_result, and do another query:
$results = $mysqli->query("CALL stored_procedure()");
$mysqli->next_result();
$results2 = $mysqli->query("CALL another_stored_procedure()");

Call count result from stored procedure MySQL in PHP

I'm trying to get a value from a stored procedure in php but I can't do it.
My stored procedure:
DROP PROCEDURE IF EXISTS sp_table;
DELIMITER $$
CREATE PROCEDURE sp_table()
BEGIN
SELECT COUNT(*) FROM table;
END$$
DELIMITER ;
My PHP code:
$recordSet_table = $conn->query("CALL sp_table()");
print_r($recordSet_table)."<br><br>";
Please try following code.
$sql = mysqli_query($connectionVariable,"CALL sp_table(#count)");
$result = mysqli_fetch_array($sql);

Insert query in mysql using stored procedure

I have to insert datas using stored procedure in mysql.Here is my SP and function call to that SP.But I can't insert values using them. Can you please verify and give me what to do?
SP is:
delimiter ; ;
DROP PROCEDURE IF EXISTS sp_insertUserDetails ; ;
CREATE PROCEDURE sp_insertUserDetails( )
BEGIN
INSERT INTO tbl_userDetails
( strEmail,bitAllowClicktoFBProfile,bitIsAbbreviateLastName, strAboutMe )
VALUES ($strEmail, $bitAllow, $bitAbbreviate, $strAbout);
END
Call to this SP from php file:
$query = mysql_query("CALL sp_insertUserDetails($strEmail, $bitAllow, $bitAbbreviate, $strAbout)");
You dont define any arguments to your SP - did you even try call it straight from SQL eg:
mysql> call sp_insertUserDetails("foo", "bar", "dave", "str");
ERROR 1318 (42000): Incorrect number of arguments for PROCEDURE test.sp_insertUserDetails; expected 0, got 4
You need something like this
DROP PROCEDURE IF EXISTS sp_name;
delimiter ;;
CREATE PROCEDURE sp_name(fname varchar (20), lname varchar(20))
BEGIN
SELECT concat('Hello ', fname, ',', lname);
END
;;
delimiter ;
just do this
HERE i am assuming that all values are in varchar
DELIMITER //
DROP PROCEDURE IF EXISTS sp_insertUserDetails;
CREATE PROCEDURE sp_insertUserDetails(
IN strEmail varchar(255),
IN bitAllow varchar(255),
IN bitAbbreviate varchar(255),
IN strAbout varchar(255)
)
BEGIN
INSERT INTO tbl_userDetails
( strEmail,bitAllowClicktoFBProfile,bitIsAbbreviateLastName, strAboutMe )
VALUES (strEmail, bitAllow, bitAbbreviate, strAbout);
END //
DELIMITER ;
and call like this
mysql_query( CALL sp_insertUserDetails($strEmail, $bitAllow, $bitAbbreviate, $strAbout) )

Get Updated Value in MySQL instead of affected rows

I've been trying to find an answer to this question, but haven't found any definitive "yes" or "no" in all my research.
I'm running a simple MySQL query like this:
UPDATE item SET `score`=`score`+1 WHERE `id`=1
Is there a way for that query to return the updated value, instead of the number of rows affected? Just as a reference, I'm doing this in PHP, so the actual code looks like:
$sql = "UPDATE item SET `score`=`score`+1 WHERE `id`=1";
$new_value = mysql_query($sql);
//Unfortunately this does not return the new value
I know I could do a second query and just SELECT the value, but I'm trying to cut down on queries as much as possible. Is there a way?
You can do it with a stored procedure that updates, and then selects the new value into an output parameter.
The following returns one column new_score with the new value.
DELIMITER $$ -- Change DELIMITER in order to use ; withn the procedure
CREATE PROCEDURE increment_score
(
IN id_in INT
)
BEGIN
UPDATE item SET score = score + 1 WHERE id = id_in;
SELECT score AS new_score FROM item WHERE id = id_in;
END
$$ -- Finish CREATE PROCEDURE statement
DELIMITER ; -- Reset DELIMITER to standard ;
In PHP:
$result = mysql_query("CALL increment_score($id)");
$row = mysql_fetch_array($result);
echo $row['new_score'];
No, there's nothing like postgresql's UPDATE ... RETURNING output_expression in MySQL (yet?).
If you don't want to run another Query SELECT then here is another way to do it. I have modified Mr. Berkowski code for reference:
DELIMITER $$
CREATE PROCEDURE increment_score
(
IN id_in INT
)
BEGIN
set #newScore := null;
UPDATE item SET score = IF((#newScore := score+1) <> NULL IS NULL, #newScore, NULL) WHERE id = id_in;
SELECT #newScore;
END
DELIMITER ;
No you cant. You could make a function or stored procedure that could do the insert and return the updated value but that would still require you to execute two queries from within the function or stored procedure.
You can create a trigger, and you will know everything about the modifications.

Categories