代码之家  ›  专栏  ›  技术社区  ›  rz.He

关于DECLARE块包含注释动态输入变量的问题

  •  0
  • rz.He  · 技术社区  · 7 年前

    我刚刚接触PL/SQL。

    我写了一个块来计算一个圆的半径和周长,如下所示:

    SET SERVEROUTPUT ON;
    
    CREATE OR REPLACE PROCEDURE cal_circle AS
    -- DECLARE
    
      pi              CONSTANT NUMBER := 3.1415926;
      radius          NUMBER := 3;
    
      -- to make it more dynamic I can set 
      -- radius NUMBER := &enter_value;
    
      circumference   DECIMAL(4,2) := radius * pi * 2;
      area            DECIMAL(4,2) := pi * radius ** 2;
    
    BEGIN
    
      -- DBMS_OUTPUT.PUT_LINE('Enter a valur of radius: '|| radius);
      dbms_output.put_line('For a circle with radius '
       || radius
       || ',the circumference is '
       || circumference
       || ' and the area is '
       || area
       || '.');
    END;
    /
    

    申报代码 radius NUMBER := &enter_value; 但是,当我在中运行脚本时 ,我总是收到这样的弹出消息 please enter the value for enter_value

    相反,如果我在声明中删除这个注释,并将其放在声明之外,那么将不再有提示。

    SET SERVEROUTPUT ON;
    
    /* to make it more dynamic, I can set 
       radius NUMBER := &enter_value;
    */
    
    CREATE OR REPLACE PROCEDURE cal_circle AS
    -- DECLARE
    
      pi              CONSTANT NUMBER := 3.1415926;
      radius          NUMBER := 3;
      circumference   DECIMAL(4,2) := radius * pi * 2;
      area            DECIMAL(4,2) := pi * radius ** 2;
    
    BEGIN
    ......
    

    这里我想澄清的是,当我试图注释动态变量时,这是否意味着DECLARE块不能接受注释?

    谢谢

    1 回复  |  直到 7 年前
        1
  •  4
  •   alexgibbs    7 年前

    您可以使用参数而不是替换变量,以允许不同的用户使用不同的pi值调用过程。

    我建议使用 FUNCTION 而不是 PROCEDURE radius ). :

    CREATE OR REPLACE PROCEDURE CAL_CIRCLE(P_RADIUS IN NUMBER, P_PI IN NUMBER) AS
      CIRCUMFERENCE DECIMAL(4, 2) := P_RADIUS * P_PI * 2;
      AREA          DECIMAL(4, 2) := P_PI * P_RADIUS ** 2;
    
      BEGIN
    
        DBMS_OUTPUT.put_line('For a circle with radius '
                             || P_RADIUS
                             || ',the circumference is '
                             || CIRCUMFERENCE
                             || ' and the area is '
                             || AREA
                             || '.' || 'Calculated with Pi=: ' || P_PI);
      END;
    /
    

    然后尝试一下:

    BEGIN
      CAL_CIRCLE(3, 3.14);
    END;
    /
    
    For a circle with radius 3,the circumference is 18.84 and the area is
    28.26.Calculated with Pi=: 3.14
    
    
    BEGIN
      CAL_CIRCLE(3, 3.14159);
    END;
    /
    
    For a circle with radius 3,the circumference is 18.85 and the area is
    28.27.Calculated with Pi=: 3.14159
    

    COMPILE DEFINE . 喜欢 DEFINE pi_value = 3.1415; &pi_value 后来

    使现代化 :为什么 SQLPlus 检测 Substitution Variable 并为其请求一个值,即使它处于 议论

    :SQL客户端必须将注释传递到服务器。预处理注释中的替换提供了更大的灵活性,并使SQL客户端更简单。客户对控制替代行为有很好的支持。在最终确定的代码中没有太多理由使用孤立替换变量。

    更长版本: 这些工具都是数据库客户机——它们有很多功能,但最重要的是它们的第一项工作是收集输入SQL,将其交付给数据库服务器并处理获取的数据。

    Comment 需要将其随附文件一起交付到数据库服务器 SQL SQL 当然,数据库中的代码也是 compiler hint

    Substitution Variables 不会像注释一样随SQL一起交付到服务器。而是对其进行评估 ,以及结果 SQLText 发送到服务器。(您可以看到 进入服务器的 替代变量 V$SQLTEXT ).

    由于服务器“利用”了注释,因此它使事情更加灵活,并简化了 SQLPlus SQLPlus , SQLDeveloper 能够

    以这种方式工作的工具没有太多缺点。

    假设一个人只想在开发过程中忽略一段代码,然后快速运行一切。如果有人 SET DEFINE OFF; 忽略变量。

    例如,它运行良好:

    SET DEFINE OFF;
    --SELECT '&MY_FIRST_IGNORED_VAR' FROM DUAL;
    -- SELECT '&MY_SECOND_IGNORED_VAR' FROM DUAL;
    SELECT 1919 FROM DUAL;
    

    '&' 在查询中, SQLPlus

    如果一个人完成了期末考试 query procedure ,具有未定义替换的剩余“孤立”注释是无效的。当开发完成时,孤立替换应该全部删除,剩下的任何内容都应该是有效的 d变量。

    下面是一个利用处理的示例 substitution 假设你想调一些表现不佳的歌曲 . 您可以在 HINT

    CREATE TABLE TEST_TABLE_1(TEST_KEY NUMBER PRIMARY KEY,
    TEST_VALUE VARCHAR2(128) NOT NULL,
    CONSTRAINT TEST_VALUE_UNQ UNIQUE (TEST_VALUE));
    
    INSERT INTO TEST_TABLE
      SELECT LEVEL, 'VALUE-'||LEVEL
      FROM DUAL CONNECT BY LEVEL <= 5000;
    

    通常是根据 TEST_VALUE 这里通常使用 UNIQUE INDEX

    SELECT TEST_VALUE FROM TEST_TABLE WHERE TEST_VALUE = 'VALUE-1919';
    

    X平面图:

    ------------------------------------------------------------------------------------  
    | Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |  
    ------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT  |                |     1 |    66 |     1   (0)| 00:00:01 |  
    |*  1 |  INDEX UNIQUE SCAN| TEST_VALUE_UNQ |     1 |    66 |     1   (0)| 00:00:01 |  
    ------------------------------------------------------------------------------------ 
    

    但是可以通过提示强制进行完整扫描。通过在提示(注释中)中使用替换变量,可以允许替换变量的值指导查询执行:

    DEFINE V_WHICH_FULL_SCAN = 'TEST_TABLE';
    SELECT /*+ FULL(&V_WHICH_FULL_SCAN) */ TEST_VALUE FROM TEST_TABLE WHERE TEST_VALUE = 'VALUE-1919';
    

    在这里,替换变量(在其注释中)更改了查询执行。

    X平面图:

    --------------------------------------------------------------------------------  
    | Id  | Operation         | Name       | Rows  | Bytes | Cost (%CPU)| Time     |  
    --------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT  |            |    23 |  1518 |     9   (0)| 00:00:01 |  
    |*  1 |  TABLE ACCESS FULL| TEST_TABLE |    23 |  1518 |     9   (0)| 00:00:01 |  
    -------------------------------------------------------------------------------- 
    

    定义 对不同的目标进行全面扫描,并快速评估每个目标对查询的影响。