PL/SQL:绑定变量不存在

发布于 2025-01-06 07:23:28 字数 364 浏览 0 评论 0原文

如何修改此过程以使其使用绑定变量

PROCEDURE KILL(user IN VARCHAR2) AS
BEGIN
  FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
  LOOP 
    execute immediate 'alter system kill session '' :1 , :2 '' immediate' 
    using rec.sid,  rec.serial; 
    END LOOP; 
END; 

它给出:

绑定变量不存在

How to modify this procedure to let it use bind variables

PROCEDURE KILL(user IN VARCHAR2) AS
BEGIN
  FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
  LOOP 
    execute immediate 'alter system kill session '' :1 , :2 '' immediate' 
    using rec.sid,  rec.serial; 
    END LOOP; 
END; 

It gives:

bind variable does not exist

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月朦胧 2025-01-13 07:23:28

语句中的绑定变量被视为文字字符串而不是占位符。如果输出正在生成的语句:

BEGIN
    FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
    LOOP
        dbms_output.put_line('alter system kill session '':1,:2'' immediate');
    END LOOP;
END;
/

...您会看到如下行:

alter system kill session ':1,:2' immediate

':1,:2' 被视为静态值,而不是两个绑定变量。您不能在动态 DDL 中使用绑定变量,并且我不确定这是否适用于 alter 命令,因此无论如何这可能是不可能的。

实现此目的的最简单方法可能是在游标中生成整个语句:

BEGIN
    FOR REC IN (
        SELECT 'alter system kill session ''' || sid ||','|| serial#
            ||''' immediate' stmt
        FROM V$SESSION WHERE username = user)
    LOOP
        dbms_output.put_line(rec.stmt);
        --execute immediate rec.stmt;
    END LOOP;
END;
/

execute 注释掉(我现在真的不想终止我的会话),您可以只看到它的命令将运行,例如:

alter system kill session '58,47157' immediate

您的方法可能仍然有缺陷,因为它会杀死正在执行该块的会话,并且它可能会也可能不会最后杀死它。我认为这属于未定义行为的领域,我真的不想尝试看看会发生什么......我怀疑这就是你真正想要的。

编辑: “有缺陷”评论基于使用 user,在我的匿名块中,它是执行用户;在您的过程中,它将是参数中的用户。不过,使用关键字作为参数名称会令人困惑,因此我建议在参数和语句中将名称更改为 p_user 之类的名称。

The bind variables in your statement are being treated as literal strings rather than place holders. If you output the statement you're generating:

BEGIN
    FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
    LOOP
        dbms_output.put_line('alter system kill session '':1,:2'' immediate');
    END LOOP;
END;
/

... you see lines like:

alter system kill session ':1,:2' immediate

The ':1,:2' is treated as a static value and not as two bind variables. You can't use bind variables in dynamic DDL, and I'm not sure if that applies to alter commands, so this may be impossible anyway.

The simplest way to achieve this may be to generate the whole statement in the cursor:

BEGIN
    FOR REC IN (
        SELECT 'alter system kill session ''' || sid ||','|| serial#
            ||''' immediate' stmt
        FROM V$SESSION WHERE username = user)
    LOOP
        dbms_output.put_line(rec.stmt);
        --execute immediate rec.stmt;
    END LOOP;
END;
/

With the execute commented out (I don't really want to kill my sessions just now) you can just see the commands it will run, like:

alter system kill session '58,47157' immediate

Your approach may still be flawed though as it will kill the session that is executing the block, and it may or may not kill it last. I think this is in the realms of undefined behaviour, and I don't really want to try it to find out what happens... I doubt that's what you actually want anyway.

Edit: 'flawed' comment was based on using user, which in my anonymous block would be the executing user; in your proc it would be the user from the parameter. Using a keyword as a parameter name is confusing though, so I'd recommend changing the name to something like p_user, in the args and the statement.

贵在坚持 2025-01-13 07:23:28

我相信这可能有效

PROCEDURE KILL(user IN VARCHAR2) AS
BEGIN
  FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
  LOOP 
    execute immediate 'alter system kill session :1 '||','|| ':2 immediate' 
    using rec.sid,  rec.serial; 
    END LOOP; 
END; 

I believe this might work

PROCEDURE KILL(user IN VARCHAR2) AS
BEGIN
  FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
  LOOP 
    execute immediate 'alter system kill session :1 '||','|| ':2 immediate' 
    using rec.sid,  rec.serial; 
    END LOOP; 
END; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文