1

我有一个 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
4

2 回答 2

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

删除程序建议项目;

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 ;
于 2012-06-25T09:05:53.963 回答
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

于 2012-06-25T08:59:54.073 回答