如何在单个会话期间同步对用户变量的访问?

时间:2015-05-26 14:52:44

标签: mysql

  1. 我需要在mysql的prepare语句中使用用户变量 存储过程。 (目的是替换表中的名称 drop table命令,无法通过?注入 通过execute using...语句传递,因为它不是数据元素)
  2. 我认为用户变量是会话范围的全局变量。
  3. 我想访问用户变量的存储过程必须是 同步以防止在调用时发生意外行为 同时在单个会话中多次(我无法阻止)。
  4. 如何执行此类同步?
    有没有机会由mysql在内部执行?

    好像是mysql get_lock()&合。使用无助的逻辑: get_lock('a')后跟get_lock('b')会破坏状态。也许我在这里非常想念一些......

    对于那些会问你"你究竟想做什么"问题:

    drop   procedure if exists drop_t_table; delimiter $$
    create procedure           drop_t_table(in in_t_table_name varchar(128))
    begin
        declare sql_drop varchar(256) default 'drop temporary table if exists ';
    
        --
        -- I would suspect sql_drop_table user variable guard should be locked here...
        --
        set @sql_drop_table = concat(sql_drop, in_t_table_name);
        --
        -- What if the procedure is preempted to another call here 
        -- and the sql_drop_table gets different table name?
        --
        prepare exe from @sql_drop_table;
        --
        -- ...and unlocked here
        --
        execute            exe;
        deallocate prepare exe;    
    end$$ delimiter ;
    

1 个答案:

答案 0 :(得分:1)

在存储过程中声明的变量是过程的本地变量。一个例子是代码中的sql_drop

每个会话基本上都是单线程的。在会话中,您不能一次做多件事。在特定会话中,无法多次调用存储过程。

如果您有多个会话,则可以从这两个会话中调用相同的存储过程。但是,DROP TABLE操作基本上是幂等:如果你不止一次调用它,它只能调用一次。它不是精确幂等的:如果表不存在则抛出错误。但是,仍然,不止一次丢弃同一张桌子并不比放弃一次更具破坏性。

临时表(a)仅对创建它们的会话可见,并且(b)在会话结束时消失。因此,明确地删除它们会遇到很多麻烦可能会有点过分。

所以,尊重你可能会过度思考这个问题。