So I've finally decided to get around to learning how to use stored procedures, and although I do have them working, I'm unsure if I'm doing it correctly - aka. the best way. So here's what I've got.
Three procedures: TryAddTag, CheckTagExists, and AddTag.
TryAddTag is the procedure that is my intermediary between other code (eg. PHP, etc...) and the other two procedures, so this is the one that gets called.
TryAddTag
DELIMITER //
CREATE PROCEDURE TryAddTag(
IN tagName VARCHAR(255)
)
BEGIN
-- Check if tag already exists
CALL CheckTagExists(tagName, @doesTagExist);
-- If it does not exist, add it
IF @doesTagExist = FALSE THEN
CALL AddTag(tagName);
END IF;
END //
DELIMITER ;
AddTag
DELIMITER //
CREATE PROCEDURE AddTag(
IN tagName VARCHAR(255)
)
BEGIN
INSERT INTO
tags
VALUES(
NULL,
tagName
);
END //
DELIMITER ;
CheckTagExists
DELIMITER //
CREATE PROCEDURE CheckTagExists(
IN
tagName VARCHAR(255),
OUT
doesTagExist BOOL
)
BEGIN
-- Check if tag exists
SELECT
EXISTS(
SELECT
*
FROM
tags
WHERE
tags.NAME = tagName
)
INTO
doesTagExist;
END //
DELIMITER ;
My problems stem from this and use of @doesTagExist.
-- Check if tag already exists
CALL CheckTagExists(tagName, @doesTagExist);
Is the the correct way to use one of these variables? And/or, how can I use a DECLARE'd variable to store the result of CheckTagExists within TryAddTag? I expected something along the lines of
...
DECLARE doesTagExist BOOL;
SET doesTagExist = CheckTagExist('str');
...
or something like that...
Return Value in SQL Server Stored ProcedureIn default, when we execute a stored procedure in SQL Server, it returns an integer value and this value indicates the execution status of the stored procedure. The 0 value indicates, the procedure is completed successfully and the non-zero values indicate an error.
A stored function can return only one value, unlike a stored procedure, which can return multiple values or an entire result set.
You cannot return table from MySQL function. The function can return string, integer, char etc. To return table from MySQL, use stored procedure, not function.
MySQL stored function returns only one value. To develop stored programs that return multiple values, you need to use stored procedures with INOUT or OUT parameters. If you are not familiar with INOUT or OUT parameters, check it out the stored procedure's parameters tutorial for the detailed information.
your stored procedure is a little over-engineered for my liking - keep it simple :)
drop table if exists tags;
create table tags
(
tag_id int unsigned not null auto_increment primary key,
name varchar(255) unique not null
)
engine=innodb;
drop procedure if exists insert_tag;
delimiter #
create procedure insert_tag
(
in p_name varchar(255)
)
proc_main:begin
declare v_tag_id int unsigned default 0;
if exists (select 1 from tags where name = p_name) then
select -1 as tag_id, 'duplicate name' as msg; -- could use multiple out variables...i prefer this
leave proc_main;
end if;
insert into tags (name) values (p_name);
set v_tag_id = last_insert_id();
-- do stuff with v_tag_id...
-- return success
select v_tag_id as tag_id, 'OK' as msg;
end proc_main #
delimiter ;
<?php
ob_start();
try{
$conn = new mysqli("localhost", "foo_dbo", "pass", "foo_db", 3306);
$conn->autocommit(FALSE); // start transaction
// create the tag
$name = 'f00';
$sql = sprintf("call insert_tag('%s')", $conn->real_escape_string($name));
$result = $conn->query($sql);
$row = $result->fetch_array();
$result->close();
$conn->next_result();
$tagID = $row["tag_id"]; // new tag_id returned by sproc
if($tagID < 0) throw new exception($row["msg"]);
$conn->commit();
echo sprintf("tag %d created<br/>refresh me...", $tagID);
}
catch(exception $ex){
ob_clean();
//handle errors and rollback
$conn->rollback();
echo sprintf("oops error - %s<br/>", $ex->getMessage());
}
// finally
$conn->close();
ob_end_flush();
?>
Stored PROCEDURES
can return a resultset. The last thing you SELECT
in a stored procedure is available as a resultset to the calling environment.. Stored FUNCTIONS
can return only a single result primitive.
You may also mark your parameters as INOUT
parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With