嵌套块中的PL / SQL变量范围

时间:2014-10-26 22:59:58

标签: plsql

我需要运行一些SQL块来测试它们,是否有一个在线应用程序,我可以插入代码并查看它触发的结果? 非常感谢! 更具体的问题如下:

<<block1>>
DECLARE 
var NUMBER;
BEGIN
var := 3;
DBMS_OUTPUT.PUT_LINE(var);

  <<block2>>
  DECLARE 
  var NUMBER;
  BEGIN
  var := 200;
  DBMS_OUTPUT.PUT_LINE(block1.var);
  END block2;
DBMS_OUTPUT.PUT_LINE(var);
END block1;

是输出: 3 3 200

或者是: 3 3 3 我读到变量的值是最近一个块中收到的值,所以第二个答案是好的吗?如果有可能的话,我很乐意在网上测试这些。 另外,<<block2>>真的是命名块的正确方法吗?

稍后编辑: 我尝试使用SQL Fiddle,但我得到一个“请构建架构”错误消息: 非常感谢,戴夫!知道为什么会这样吗?

create table log_table
( message varchar2(200)
)


<<block1>>
DECLARE 
var NUMBER;
BEGIN
var := 3;

insert into log_table(message) values (var)
select * from log_table

  <<block2>>
  DECLARE 
  var NUMBER;
  BEGIN
  var := 200;
  insert into log_table(message) values (block1.var || ' 2nd') 
  select * from log_table
  END block2;
insert into log_table(message) values (var || ' 3rd') 
select * from log_table
END block1;

1 个答案:

答案 0 :(得分:4)

回答你的三个问题。

  1. 您可以将SQL小提琴与Oracle 11g R2一起使用:http://www.sqlfiddle.com/#!4。但是,这不允许您使用dbms_output。您必须插入/选择表才能看到PL / SQL脚本的结果。

  2. 答案是3 3 3.一旦内部块被END-ed,变量就不再存在/具有范围。您无法再访问它们。

  3. 块命名是正确的,但是,您不需要命名块,它们可以是完全匿名的。

  4. 修改

    所以在使用SQL Fiddle之后,似乎它实际上并不支持命名块(尽管我有一个实际的Oracle数据库来确认我之前说过的内容)。

    然而,您可以使用存储过程和内部过程(这是两个非常重要的PL / SQL特性)来演示变量作用域的工作方式。

    在我做到这一点之前,我发现你的代码有三个问题:

    1. 您需要使用分号终止插入语句。
    2. 您需要在第三次插入后提交事务。
    3. 在PL / SQL中,您不能简单地执行select语句并获得结果,您需要选择一些变量。这将是一个简单的更改,但因为我们不能使用dbms_output来查看变量,它对我们没有帮助。而是执行插入,然后提交,然后从表中进行选择。
    4. 在SQL Fiddle的左侧窗格中,将查询终止符设置为“//”,然后粘贴到下面的“构建模式”中:

      create table log_table
      ( message varchar2(200)
      )
      //
      
      create or replace procedure proc1 as
      var NUMBER;
      
         procedure proc2 as 
            var number;
         begin
            var := 200;
            insert into log_table(message) values (proc1.var || ' 2nd'); 
         end;
      
      begin
         var := 3;
      
         insert into log_table(message) values (var || ' 1st');
      
         proc2;
      
         insert into log_table(message) values (var || ' 3rd');
      
         commit;
      
      end;
      //
      
      begin
      proc1;
      end;
      //
      

      然后在右侧面板中运行此SQL:

      select * from log_table
      

      你可以看到proc2.var没有proc2之外的范围。此外,如果您明确尝试在proc2之外使用proc2.var,则会引发异常,因为它超出了范围。