Slowly working through change MSSQL database to MySQL and the final problem is as follows :-
CREATE DEFINER=`root`#`localhost` PROCEDURE `user_GetUserInRole`(
IN $EMail nvarchar(256),
IN $RoleName nvarchar(256),
INOUT $ReturnStatus bit)
BEGIN
DECLARE $UserId char(38);
DECLARE $RoleId char(38);
DECLARE $this_count INT;
SET $UserId = (SELECT UserId FROM server.`user_Data` WHERE EMail = $EMail);
SET $RoleId = (SELECT RoleId FROM server.`user_Roles` WHERE RoleName = $RoleName);
SET $this_count = (SELECT COUNT(*) FROM user_UsersInRoles WHERE UserId = $UserId AND RoleId = $RoleId);
IF ($this_count > 0) THEN
SET $ReturnStatus = 1;
ELSE
SET $ReturnStatus = 0;
END IF;
END
Always returns 0, even when I know the count is equal to 1. I believe that there is an issue with the input variables not being recognized properly by the Where clause in both Select UserId and Select RoleId statements, but I can't see what I'm doing differently to the various helps I've found.
Any help, as always, is greatly appreciated.
EDIT
I have since tried running a simple insert command
CREATE DEFINER=`root`#`localhost` PROCEDURE `test`()
BEGIN
INSERT INTO server.`test_table`
VALUES('test', 'test2');
END
And this hasn't worked either. This leads me to believe that it's actually more of a problem with the PDO call.
$command = "EXEC test";
$stpro = $conn->prepare($command);
$returnvalue = $stpro->execute();
I know that $conn works as straight sql calls in my php definitely work.
EDIT 2
So, turns out EXEC should have been CALL. This now works with the test. As soon as I put any parameters into it though it stops working. Any thoughts?
No need of $Email. Make your parameter declaration like
IN email nvarchar(256)
Change your select inside procedure as below
FROM
SET $UserId = (SELECT UserId FROM server.`user_Data` WHERE EMail = $EMail);
TO
SET #UserId := (SELECT UserId FROM server.`user_Data` WHERE EMail = email);
with that, your procedure should look like
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `user_GetUserInRole`(
IN email nvarchar(256),
IN rolename nvarchar(256),
INOUT retstatus bit)
BEGIN
SET #UserId := (SELECT UserId FROM server.`user_Data` WHERE EMail = email);
SET #RoleId := (SELECT RoleId FROM server.`user_Roles`
WHERE RoleName = rolename);
SET #this_count := (SELECT COUNT(*) FROM user_UsersInRoles
WHERE UserId = #UserId AND RoleId = #RoleId);
IF (#this_count > 0) THEN
SET retstatus = 1;
ELSE
SET retstatus = 0;
END IF;
END$$
DELIMITER ;
Okay, so at this this where I am at the moment #meda. Thought I'd post as a separate "answer" to avoid any confusion.
The current Procedure is :-
CREATE DEFINER=`root`#`localhost` PROCEDURE `user_GetUserInRole`(
IN email nvarchar(256),
IN rolename nvarchar(256),
OUT returnstatus int)
BEGIN
SELECT #UserId := UserId FROM server.`user_data` WHERE EMail = email;
SELECT #RoleId := RoleId FROM server.`user_roles` WHERE RoleName = rolename;
SELECT #this_count := COUNT(*) FROM server.`user_usersinroles` WHERE UserId = #UserId AND RoleId = #RoleId;
IF (#this_count > 0) THEN
SET #returnstatus = 1;
ELSE
SET #returnstatus = 0;
END IF;
END
This is launched by the php :-
$command = "CALL user_GetUserInRole (?, ?, ?)";
$role = "Admin";
$stpro = $conn->prepare($command);
$stpro->bindParam(1, $_SESSION['vaild_user']);
$stpro->bindParam(2, $role);
$stpro->bindParam(3, $returnvalue, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);
$success = $stpro->execute();
if($success)
{
$returnvalue = $stpro->fetch(PDO::FETCH_ASSOC);
}
If I remove the OUT returnstatus int from the Procedure and the third parameter from the php it runs perfectly and if I add an Insert command for debug purposes in the procedure I am getting the correct answers from the queries.
However, as soon as the OUT is returned to the statement the whole thing falls over and $success = $stpro->execute(); returns "false" every time.
Okay, so in case anyone else runs into this problem, I finally have the answer. The problem is that PDO does not allow you to bind parameters to OUT variables properly. As a result you need to run two queries in order for the CALL to run properly. This allows the variable to be read though the $output arrange and away you go.
$role = "Admin";
$command = "CALL user_GetUserInRole ('" . $_SESSION['vaild_user'] . "', '" . $role . "', #returnvalue)";
$conn->query($command);
$output = $conn->query("SELECT #returnvalue")->fetch(PDO::FETCH_ASSOC);
if ($output["#returnvalue"] == 1)
{
$admin = true;
}
PDOStatement::execute will return a boolean value based on success or failure of the stored procedure call.
So $returnvalue is not really what you think, try this instead:
$command = "EXEC test ?";
$param = "123";
$stpro = $conn->prepare($command);
$stpro ->bindParam(1, $param, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 12);
$success = $stpro->execute();
if($success){
$returnvalue = $stpro->fetch(PDO::FETCH_ASSOC);
var_dump($returnvalue);
}else{
echo "execute() failed!";
}
Related
I have a stored procedure that when called updates few tables and eventually returns an integer value.
When I call this stored procedure using SQL Pro tool, I get back a result as expected. The SQL that is auto-generated by the tool is this;
DECLARE #return_value int
EXEC #return_value =
dbo.GetNextReference
#c_tableName = 'prp',
#c_offYear = 'rcs14'
SELECT
'Return Value' = #return_value
However, I can't seem to get the same results or any results when I try to execute this using PHP PDO driver.
This is my code so far;
$conn = $this->getPDO();
$sql = "CALL GetNextReference (? , ?)";
$stmt = $conn->prepare($sql);
$tbl = 'prp';
$year = "rcs14";
$stmt->execute([$tbl, $year]);
$results = $stmt->fetchAll();
The statement executes without any errors but the results come back as an empty array.
What am I missing?
Sorry, I can't post the actual stored procedure as I am not permitted.
If I understand your question correctly and if you want to check the result of stored procedure execution, you may try with this:
<?php
# Connection
$server = 'server\instance,port';
$database = 'database';
$uid = 'user';
$pwd = 'password';
# Statement
try {
$conn = new PDO("sqlsrv:server=$server;Database=$database", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch( PDOException $e ) {
die( "Error connecting to SQL Server" );
}
try {
$sql = "{? = call GetNextReference (? , ?)}";
# This should work also.
#$sql = "exec ? = GetNextReference (? , ?)";
$spresult = 0;
$tbl = 'prp';
$year = "rcs14";
$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $spresult, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE);
$stmt->bindParam(2, $tbl);
$stmt->bindParam(3, $year);
$stmt->execute();
# Next line for single resultset
#$results = $stmt->fetchAll();
# Multiple resultsets
do {
$results = $stmt->fetchAll();
print_r($results, true);
} while ($stmt->nextRowset());
} catch( PDOException $e ) {
die( "Error connecting to SQL Server" );
}
$stmt = null;
$conn = null;
echo 'Stored procedure return value : '.$spresult."</br>";
?>
Op has asked for an example of an OUTPUT parameter. it doesn't specifically answer their question, however, is far too long for a comment:
USE Sandbox;
GO
--Sample Table
CREATE TABLE dbo.TestTable (ID int IDENTITY(1,1),
SomeString varchar(20));
GO
--Sample proc
CREATE PROC dbo.TestSP #SomeString varchar(20), #ID int OUTPUT AS
--You cannot OUTPUT from an INSERT into a scalar variable, so we need a table variable
DECLARE #IDt table(ID int);
INSERT INTO dbo.TestTable (SomeString)
OUTPUT inserted.ID
INTO #IDt
SELECT #SomeString;
--Now set the scalar OUTPUT parameter to the value in the table variable
SET #ID = (SELECT ID FROM #IDt); --this works, as the SP is designed for only one row insertion
GO
DECLARE #SomeString varchar(20) = 'abc', #ID int;
EXEC dbo.TestSP #SomeString = #SomeString,
#ID = #ID OUTPUT; --ID now has the value of the IDENTITY column
--We can check here:
SELECT #ID AS OutputID;
SELECT *
FROM dbo.TestTable;
GO
--Clean up
DROP PROC dbo.TestSP;
DROP TABLE dbo.TestTable;
GO
Simple example
CREATE PROCEDURE [dbo].[InsertLoginInPHP]
#login as nvarchar(50), #password as nvarchar(50), #resultOK as int, #resultnot as int
AS
BEGIN
SET #resultOK = 10
SET #resultnot = 1
IF EXISTS (SELECT * FROM Users WHERE Login = #login)
BEGIN
SELECT #resultnot as return // 1
END
ELSE
BEGIN
INSERT INTO Users (Login,Password) VALUES(#login,#password)
SELECT #resultOK as return // 10
END
END
and In php
$query = ("EXECUTE InsertLogin :login, :password");
$query_stored = $conn->prepare($query);
$query_stored->bindvalue(':login', $login);
$query_stored->bindvalue(':password', $password);
$query_stored->execute();
How can I get return value ( #resultnot or #resultOK ) in php?
And How can I get and use return value in JSON?
Like this
json_encode(array('status'=>'Ok','return'=>$query_sotored[resultOK])));
You need to fetch a row from the statement, then access the column from the array this returns.
$query = ("EXECUTE InsertLogin :login, :password");
$query_stored = $conn->prepare($query);
$query_stored->bindvalue(':login', $login);
$query_stored->bindvalue(':password', $password);
$query_stored->execute();
$row = $query_stored->fetch(PDO::FETCH_ASSOC);
echo json_encode(array('status'=>'Ok','return'=>$row['return'])))
I Know there are multiple tutorials and stackoverflow answer for the said Question. But none helped.
From my controller I am passing my data as an array.
Now the Stored Procedure created looks like this
BEGIN
DECLARE recCnt Int DEFAULT 0;
#DECLARE rm_id_val Bigint(19);
select count(*) into recCnt from users where user_name = user_name_in;
IF recCnt > 0 THEN
SET rm_id_val = 0;
ELSE
#SET rm_id = rm_id_gen();
INSERT INTO users(user_category, user_name, facebook_id,
password, email, mobile_no, city_name, country_name, view_count, user_type, signup_date, updated_on)
values (user_cat_in,user_name_in, facebook_id_in,
password_in, email_in, mobile_no_in, city_name_in, country_name_in, 0, user_type_in, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP());
select rm_id into rm_id_val from users where user_name=user_name_in;
INSERT INTO activation (rm_id, no_of_attempt, activation_key, activation_status)
VALUES (rm_id_val,0, activation_key_in, 0);
END IF;
END
Here rm_id_val is OUT param and rest are IN
I passed the $data array to model and the model looks like this
$sql = "CALL signup";
$query = $this->db->query($sql, $data);
return $query->result();
Needless to Say It did not work. Then I tried using a solution from stackoverflow
$this->db->trans_start();
$p1 = $data['user_cat_in'];
$p2 = $data['user_name_in'];
$p3 = $data['facebook_id_in'];
$p4 = $data['password_in'];
$p5 = $data['email_in'];
$p6 = $data['mobile_no_in'];
$p7 = $data['city_name_in'];
$p8 = $data['country_name_in'];
$p9 = $data['view_count'];
$p10 = $data['user_type_in'];
$p11 = $data['signup_date'];
$p12 = $data['updated_on'];
$success = $this->db->query("CALL signup('$p1','$p2','$p3','$p4','$p5','$p6','$p7','$p8','$p9','$p10',#rm_id_val);");
print_r("CALL signup('$p1','$p2','$p3','$p4','$p5','$p6','$p7','$p8','$p9','$p10',#rm_id_val);"); exit();
$out_param_query = $this->db->query('select #rm_id_val as out_param;');
$this->db->trans_complete();
return $success;
Well No output again.
Then I tried MySql Console and executed the following
CALL signup('musician','acacascsacsca','0','cascsacsac','ascascascacacac','acacac','acascacsacs','India','0','1',#rm_id_val);
select #rm_id_val as rmid;
This resulted in
#1414 - OUT or INOUT argument 1 for routine ragamixdb.signup is not a variable or NEW pseudo-variable in BEFORE trigger
Please help me to get this proc called via codeigniter
Thanks and appreciated
Had you tried to set mysql variables.
try to assign/convert php variable to mysql variable using this syntax.
SET #running_sum = 0;
use set of syntaxs in CI like this ,
$this->db->query("SET #your_mysql_variable = ".$your_php_variable);
$this->db->query("SET #your_another_mysql_variable = ".$your_another php_variable);
$this->db->query("CALL your_procedure()");
I'm trying to get a value from a string declared inside a stored procedure, so that I can use it in my PHP-code.
The procedure:
DELIMITER //
CREATE PROCEDURE InsertName
(IN NewName varchar(50), OUT NewID char(25))
BEGIN
DECLARE NewID CHAR(25) DEFAULT (SELECT CONCAT((SELECT unix_timestamp()), (SELECT FLOOR(RAND() * 1000000000000000))));
INSERT INTO User
VALUES (NewID, NewName);
END;
//
DELIMITER ;
The PHP-code that calls the procedure:
$name = $_POST['name'];
$sth = $pdo->prepare("CALL InsertName('$name', #idcode)");
$sth->execute();
$sth->closeCursor();
$sth = $pdo->query("SELECT #idcode AS idcode");
$newid = $sth->fetch(PDO::FETCH_ASSOC);
$idcode=$newid['idcode'];
echo $idcode . " blarg";
The page I'm trying to display only shows " blarg", and nothing else. Something is wrong when fetching the OUT parameter. I have also tried with
SELECT NewID;
in the procedure, it still gives the same result.
i am using php with mysql.
My stored proc returns values via out parameter via Toad4MySQL but when it comes to php Pdo, it does not capture the return value.
here's my code
$validusername= 'x';
$validemail = 'x';
$validkey = 'x';
$query = $pdo->prepare("Call InsertNewUser(:fullname, :usernamex, :email, :password, :con_password, #:validusername, #:validemail, #:validkey); ");
$query->bindParam(':fullname', $fullname , PDO::PARAM_STR);
$query->bindParam(':usernamex', $usernamex , PDO::PARAM_STR);
$query->bindParam(':email', $email, PDO::PARAM_STR);
$query->bindParam(':password', $password, PDO::PARAM_STR);
$query->bindParam(':con_password', $con_password, PDO::PARAM_STR);
$query->bindParam(':validusername', $validusername, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT);
$query->bindParam(':validemail', $validemail , PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT);
$query->bindParam(':validkey', $validkey , PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT);
$results = $query-> execute();
echo $validemail ; # returns x but not the value that i wanted.
Can anyone help me with this puzzle ?
My Stored Procedure code:
DROP PROCEDURE IF EXISTS InsertNewUser;
CREATE PROCEDURE xxx.`InsertNewUser`(
fullname varchar(255),
username varchar(255),
email_address varchar(255),
password varchar(255),
con_password varchar(255),
out validusername varchar(10),
out validemail varchar(10),
out validkey varchar(155)
)
BEGIN
declare xcnt_1 int;
declare xcnt_2 int;
declare xkey varchar(155);
set xkey = MD5(RAND());
select count(*) into xcnt_1 from user where user.email_address = email_address;
select count(*) into xcnt_2 from user where user.username = username;
if xcnt_1 > 0 then
set validemail = 'false';
else
set validemail = 'true';
end if;
if xcnt_2 > 0 then
set validusername = 'false';
else
set validusername = 'true';
end if;
if xcnt_1 = 0 and xcnt_2 = 0 then
set validkey = xkey;
INSERT INTO user
(user.fullname, user.username, user.email_address, user.password, user.con_password, user.md5validate)
VALUES
(fullname, username, email_address, password, con_password, xkey);
else
set validkey = 'false';
end if;
commit;
END;
ah... finally solved this problem :
for some unknown reasons, i have to change the call statement to :
Call InsertNewUser(:fullname, :usernamex, :email, :password, :con_password, #validusername_global, #validemail_global, #validkey_global);
and use this line of codes to get the data...
$SQL = ' select #validusername_global as validusername, #validemail_global as validemail, #validkey_global as validkey';
$query = $pdo->query($SQL);
while($row = $query->fetch(PDO::FETCH_ASSOC))
{
print_r($row);
}
Executing the PDO prepared statement won't have any effect on $validemail.
After $results = $query->execute();, try adding print_r($query->fetchAll()); to get a better sense of what is being returned from MySQL to PHP when your PHP statement runs the MySQL stored procedure.
Keep in mind that $results is just going to be a boolean indicating whether or not the statement could be executed.
From the PDO manual:
int $length
Length of the data type.
To indicate that a parameter is an OUT
parameter from a stored procedure, you
must explicitly set the length.
http://php.net/manual/en/pdostatement.bindparam.php
You have omitted this parameter, which would explain why it is not being used as an OUT parameter.
if you set $validemail=x and dont manipulate/change nothing with $validemail in later code then obvioulsy echo $validemail will returns x.? whats' wrong with that? either u missed to paste some code
Try wrapping your prepare statement, bind parameters and execute in try, catch blocks and see if PDO spits out any sort of error.