【MYSQL】存储过程示例

GROUPEMP_EXISTS:

CREATE DEFINER=`ucheck`@`%` PROCEDURE `GROUPEMP_EXISTS`(IN `projectype` varchar(50), IN `groupid` int(11), IN `empid` int(11))
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
DECLARE projectid VARCHAR(10) DEFAULT NULL;
DECLARE result VARCHAR(200) DEFAULT '';
DECLARE project CURSOR FOR SELECT project_id FROM u_project WHERE u_project.project_type=projectype;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET projectid=NULL;
OPEN project;
    search_Loop:LOOP
        FETCH project INTO projectid;
        IF projectid IS NOT NULL THEN
            SET @num = 0;
            SET @sqlstr = CONCAT("SELECT COUNT(*) into @num FROM project_",projectid,".u_project_group_emp WHERE group_id=",groupid," AND emp_id=",empid); 
            PREPARE stmt FROM @sqlstr;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
            IF @num!=0 THEN
                IF result='' 
                THEN
                    SET result =projectid;
                ELSE
                    SET result=CONCAT(result,',',projectid);
                END IF;
            END IF;
        ELSE
            LEAVE search_loop;
        END IF;
    END LOOP search_loop;
CLOSE project;
SELECT result;
END
GROUP_EXISTS:

CREATE DEFINER=`ucheck`@`%` PROCEDURE `GROUP_EXISTS`(IN `projectype` varchar(50), IN `groupid` int(11))
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT '根据指定的组id,查询所有库,返回存在该组id的项目id (1,2,3,4)'
BEGIN
DECLARE projectid VARCHAR(10) DEFAULT NULL;
DECLARE result VARCHAR(200) DEFAULT '';

DECLARE project CURSOR FOR SELECT project_id FROM u_project WHERE u_project.project_type=projectype;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET projectid=NULL;
OPEN project;
    REPEAT
        FETCH project INTO projectid;
        IF projectid IS NOT NULL
        THEN
            SET @num = 0;
            SET @sqlstr = CONCAT("SELECT COUNT(*) into @num FROM project_",projectid,".u_project_group_emp WHERE group_id=",groupid); 
            PREPARE stmt FROM @sqlstr;
            EXECUTE stmt;
            DEALLOCATE PREPARE stmt;
            IF @num!=0 THEN
                IF result='' 
                THEN
                    SET result =projectid;
                ELSE
                    SET result=CONCAT(result,',',projectid);
                END IF;
            END IF;
        END IF;
    UNTIL projectid IS NULL END REPEAT;
CLOSE project;
SELECT result;
END
UPDATE_REVIEWOK

CREATE DEFINER=`ucheck`@`%` PROCEDURE `UPDATE_REVIEWOK`(IN `projectId` int, IN `shotId` int, OUT `result` int)
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    DECLARE EXIT HANDLER FOR SQLEXCEPTION SET result=-1;
    SET result=1;
    
    SET @reel='';
    SET @shot=0;
    set @sql=concat("SELECT shot_lock,shot_reel INTO @shot,@reel  FROM project_",projectId,".u_shot WHERE shot_id=",shotId," FOR UPDATE");
    prepare stmt from @sql;
    execute stmt;
    deallocate prepare stmt;

IF @shot=1 THEN
    set @sql=concat("UPDATE project_",projectId,".u_mastershotlist_part,project_",projectId,".u_mastershotlist SET dmap_review_ok=NULL WHERE u_mastershotlist.shot_id=",shotId," AND u_mastershotlist.id=u_mastershotlist_part.mastershotlist_id");
    prepare stmt from @sql;
    execute stmt;
    deallocate prepare stmt;
ELSE
    SET @picstatus=0;
    set @sql=concat("SELECT status_id INTO @picstatus FROM uPlatform.u_status WHERE status_name='Review OK' AND status_type=0");
    prepare stmt from @sql;
    execute stmt;
    deallocate prepare stmt;
    SET @reviewoknum=0;
    SET @totalnum=0;
    set @sql=concat("SELECT SUM(IF(picture_status=",@picstatus,",1,0))AS reviewok,COUNT(*)AS totalNum INTO @reviewoknum,@totalnum FROM reel_",projectId,"_",@reel,".u_picture WHERE picture_shot=",shotId," AND picture_lock=0");
    prepare stmt from @sql;
    execute stmt;
    deallocate prepare stmt;
    IF @totalNum=0 THEN
        SET @per=NULL;
        set @sql=concat("UPDATE project_",projectId,".u_mastershotlist_part,project_",projectId,".u_mastershotlist SET dmap_review_ok=NULL WHERE u_mastershotlist.shot_id=",shotId," AND u_mastershotlist.id=u_mastershotlist_part.mastershotlist_id");
    ELSE
        SET @per=@reviewoknum /@totalnum;
        set @sql=concat("UPDATE project_",projectId,".u_mastershotlist_part,project_",projectId,".u_mastershotlist SET dmap_review_ok=",@per," WHERE u_mastershotlist.shot_id=",shotId," AND u_mastershotlist.id=u_mastershotlist_part.mastershotlist_id");
    END IF;
    prepare stmt from @sql;
    execute stmt;
    deallocate prepare stmt;

END IF;

END
mysql> PREPARE prod FROM "INSERT INTO examlple VALUES(?,?)";   
mysql> SET @p='1';   
mysql> SET @q='2';   
mysql> EXECUTE prod USING @p,@q;   
mysql> SET @name='3';   
mysql> EXECUTE prod USING @p,@name;   
mysql> DEALLOCATE PREPARE prod;  

#EXECUTE stmt USING @a;这样的语句USING后面的变量也只能用set @var=value这种,declare和参数传入的变量不行。

 使用 PREPARE 的几个注意点: 
A:PREPARE stmt_name FROM preparable_stmt;预定义一个语句,并将它赋给 stmt_name ,tmt_name 是不区分大小写的。
B: 即使 preparable_stmt 语句中的 ? 所代表的是一个字符串,你也不需要将 ? 用引号包含起来。 
C: 如果新的 PREPARE 语句使用了一个已存在的 stmt_name ,那么原有的将被立即释放! 即使这个新的 PREPARE 语句因为错误而不能被正确执行。
D: PREPARE stmt_name 的作用域是当前客户端连接会话可见。 
E: 要释放一个预定义语句的资源,可以使用 DEALLOCATE PREPARE 句法。 
F: EXECUTE stmt_name 句法中,如果 stmt_name 不存在,将会引发一个错误。 
G: 如果在终止客户端连接会话时,没有显式地调用 DEALLOCATE PREPARE 句法释放资源,服务器端会自己动释放它。 
H: 在预定义语句中,CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE, 和大部分的 SHOW 句法被支持。
I: PREPARE 语句不可以用于存储过程,自定义函数!但从 MySQL 5.0.13 开始,它可以被用于存储过程,仍不支持在函数中使用!

原文地址:https://www.cnblogs.com/mqxs/p/6405629.html