STORED程序中的变量

时间:2012-06-25 08:56:14

标签: mysql

我有一个Web应用程序,可以在需要时调用许多存储过程。

在每个存储过程中,我在这些存储过程中声明了局部变量。

我希望这些局部变量特定于该特定存储过程。因此,当执行此存储过程时,在过程中声明的局部变量是特定于该存储过程的,并且应该在该过程退出时被确定。

我在我的存储过程中使用了相同的局部变量名称,但是当执行另一个存储过程时,似乎没有重新设置这些变量。

我也在使用执行查询的PREPARE STATEMENTS,在执行这些语句后,我正在取消分配它们。 为什么我仍然没有重置这些变量问题?

这是存储过程:

        CREATE DEFINER=`root`@`localhost` PROCEDURE `suggested_projects`(
               IN userName varchar(20),
               OUT projectCode int,
               OUT projectName text,
               OUT projectCreationDate DATETIME,
               OUT projectEndDate DATETIME,
               OUT projectStatus varchar(8),
               OUT noOf smallInt)
        BEGIN
        DECLARE
            l_cnt, l_occ int;

        DECLARE
            l_table_name varchar(30);

        DECLARE
            l_create,droptable, l_select_cnt, l_select_cnt2, l_select_cnt3, l_other_expertise, l_query1,
            l_delete_other, l_final_query longtext;

           set l_table_name = concat("tmp_rec_",userName);

           set @l_select_cnt = concat("SELECT count(1) into @l_cnt
                                       from information_schema.tables
                                      where table_schema = 'greptech'
                                      and table_name = '", l_table_name, "'");

           PREPARE stmt2 FROM @l_select_cnt;
           EXECUTE stmt2;
           DEALLOCATE PREPARE stmt2;

           if @l_cnt > 0 then
               set @droptable = concat("drop table ", l_table_name);

               PREPARE stmt1 FROM @droptable;
               EXECUTE stmt1;
               DEALLOCATE PREPARE stmt1;
           END IF;


           set @l_create = concat("CREATE TABLE ", l_table_name,
                               " SELECT a.expertise_desc
                                  from expertise a
                                 inner join users_expertise b
                                    on a.expertise_code = b.expertise_code
                                   and b.sp_user_name = '", userName , "'");

               PREPARE stmt3 FROM @l_create;
               EXECUTE stmt3;
               DEALLOCATE PREPARE stmt3;

           set @l_select_cnt2 = concat("SELECT other_expertise into @l_other_expertise
                                       from users_expertise
                                      where sp_user_name = '", userName, "' ",
                                      "and expertise_code = 'OTHER'");

           PREPARE stmt4 FROM @l_select_cnt2;
           EXECUTE stmt4;
           DEALLOCATE PREPARE stmt4;

           if (@l_other_expertise IS NOT NULL) then
                -- Example RESULT : INSERT INTO tmp_rec_n10000 VALUES('DWH'),('TESTING'),('ARCHITECTURE')
                set @l_query1 = concat("INSERT INTO ", l_table_name, " VALUES('", REPLACE(@l_other_expertise,',','\'),(\''), "')");

                PREPARE stmt5 FROM @l_query1;
                EXECUTE stmt5;
                DEALLOCATE PREPARE stmt5;
            END IF;

           set @l_delete_other = concat("DELETE from ", l_table_name,
                                       " where expertise_desc = 'Other'");

           PREPARE stmt6 FROM @l_delete_other;
           EXECUTE stmt6;
           DEALLOCATE PREPARE stmt6;

           set @l_final_query = concat("SELECT a.project_code as projectCode, a.project_name as projectName, a.project_creation_date as projectCreationDate, a.project_end_date as projectEndDate, a.project_status as projectStatus, count(c.project_code) as noOf from projects a inner join ", l_table_name, " b on a.project_name like concat(\"%\",trim(b.expertise_desc),\"%\") OR a.project_description like concat(\"%\",trim(b.expertise_desc),\"%\") left join project_ids c on c.project_code = a.project_code group by a.project_code");

           PREPARE stmt7 FROM @l_final_query;
           EXECUTE stmt7;
           DEALLOCATE PREPARE stmt7;

        END

2 个答案:

答案 0 :(得分:2)

您可以声明本地变量,例如

DECLARE xname VARCHAR(5) DEFAULT 'bob';

会话变量可以像这样声明

SET @var := 1

您应该在存储过程中使用局部变量。这些将被重新删除,并且它们被定义为块的结尾。

修改

示例存储过程:

delimiter |
create procedure test_proc(myname varchar(100))
begin
    declare some_id int;
    select id into some_id
    from mytable
    where `name` = myname;

    select some_id;
end |
delimiter ;

编辑2

drop procedure suggest_projects;

delimiter |

CREATE DEFINER=`root`@`localhost` PROCEDURE `suggested_projects`(
           IN userName varchar(20),
           OUT projectCode int,
           OUT projectName text,
           OUT projectCreationDate DATETIME,
           OUT projectEndDate DATETIME,
           OUT projectStatus varchar(8),
           OUT noOf smallInt)
    BEGIN
    DECLARE
        l_cnt, l_occ int;

    DECLARE
        l_table_name varchar(30);

    DECLARE
        l_create,droptable, l_select_cnt, l_select_cnt2, l_select_cnt3, l_other_expertise, l_query1,
        l_delete_other, l_final_query longtext;

       select concat("tmp_rec_",userName) into l_table_name;

       select concat("SELECT count(1) into @l_cnt
                                   from information_schema.tables
                                  where table_schema = 'greptech'
                                  and table_name = '", l_table_name, "'") 
                                  into l_select_cnt;

       set @query = l_select_cnt;
       PREPARE stmt2 FROM @l_select_cnt;
       EXECUTE stmt2;
       DEALLOCATE PREPARE stmt2;

       if l_cnt > 0 then
           select concat("drop table ", l_table_name) into droptable;

           set @query = droptable;
           PREPARE stmt1 FROM @query;
           EXECUTE stmt1;
           DEALLOCATE PREPARE stmt1;
       END IF;


       select concat("CREATE TABLE ", l_table_name,
                           " SELECT a.expertise_desc
                              from expertise a
                             inner join users_expertise b
                                on a.expertise_code = b.expertise_code
                               and b.sp_user_name = '", userName , "'")
                               into l_create;

           set @query = l_create;
           PREPARE stmt3 FROM @query;
           EXECUTE stmt3;
           DEALLOCATE PREPARE stmt3;

       select concat("SELECT other_expertise into @l_other_expertise
                                   from users_expertise
                                  where sp_user_name = '", userName, "' ",
                                  "and expertise_code = 'OTHER'")
                                  into l_select_cnt2;

       set @query = l_select_cnt2;
       PREPARE stmt4 FROM @query;
       EXECUTE stmt4;
       DEALLOCATE PREPARE stmt4;

       if (@l_other_expertise IS NOT NULL) then
            -- Example RESULT : INSERT INTO tmp_rec_n10000 VALUES('DWH'),('TESTING'),('ARCHITECTURE')
            set @l_query1 = concat("INSERT INTO ", l_table_name, " VALUES('", REPLACE(@l_other_expertise,',','\'),(\''), "')");

            PREPARE stmt5 FROM @query;
            EXECUTE stmt5;
            DEALLOCATE PREPARE stmt5;
        END IF;

       select concat("DELETE from ", l_table_name,
                                   " where expertise_desc = 'Other'")
                                   into l_delete_other;

       set @query = l_delete_other;
       PREPARE stmt6 FROM @query;
       EXECUTE stmt6;
       DEALLOCATE PREPARE stmt6;

       select  concat("SELECT a.project_code as projectCode, a.project_name as projectName, a.project_creation_date as projectCreationDate, a.project_end_date as projectEndDate, a.project_status as projectStatus, count(c.project_code) as noOf from projects a inner join ", l_table_name, " b on a.project_name like concat(\"%\",trim(b.expertise_desc),\"%\") OR a.project_description like concat(\"%\",trim(b.expertise_desc),\"%\") left join project_ids c on c.project_code = a.project_code group by a.project_code")
              into l_final_query;

       set @query = l_final_query;
       PREPARE stmt7 FROM @query;
       EXECUTE stmt7;
       DEALLOCATE PREPARE stmt7;

    END; |

delimiter ;

答案 1 :(得分:0)

我只在同一数据库连接上调用的存储过程使用的临时表中遇到此问题。临时表当然是为此连接共享的:

这是我使用的解决方案,在每次创建之前删除:

drop table if exists t_tempTable;
create temporary table t_tempTable(.

准备好的陈述也是全球性的,见这里: http://dev.mysql.com/doc/refman/5.0/en/local-variable-scope.html