【问题标题】:How combine local variable in Oracle?Oracle中如何组合局部变量?
【发布时间】:2016-02-12 09:11:55
【问题描述】:

我想将程序从 sqlserver 转换为 oracle 11g。 这是我在 sqlserver 中的 sp

declare
@nwhere varchar(200);
@Select varchar(200);
@from varchar(200);
@final varchar(200);

set @select='select * '
set @from='from table '
set @where='where 1=1'
set @final=@select+@from+@where

execute (@final)

如何在 oracle 中组合局部变量,如 @final=@select+@from+@where? thanks

【问题讨论】:

    标签: sql-server oracle oracle11g


    【解决方案1】:

    在 oracle 中附加变量就像

    最终=选择 ||来自 ||在哪里

    【讨论】:

      【解决方案2】:

      您可以使用 || 连接字符串运营商:

      DECLARE
        v_where VARCHAR2(200);
        v_select VARCHAR2(200);
        v_from VARCHAR2(200);
        v_final VARCHAR2(200); 
        v_row table%ROWTYPE;
        c_cursor SYS_REFCURSOR;
      BEGIN
        v_select := 'select * ';
        v_from := 'from table ';
        v_where := 'where 1=1';
        v_final :=  v_select || from || where;
      
        OPEN c_cursor FOR v_final;
        FETCH c_cursor INTO v_row; 
        CLOSE c_cursor;
      END;
      

      【讨论】:

        【解决方案3】:

        使用 || 运算符连接字符串

        如果您需要保持 vars 的 ID 与 @ 一样,您需要添加 "

        执行您需要使用的语句execute immediatedbms_sql

        declare
        "@select" varchar(200) := 'select * ';
        "@from" varchar(200) := ' from table ';
        "@where" varchar(200) := ' where 1=1';
        "@final" varchar(200) :="@select"||"@from"||"@where";
        begin
          --test result string
          --dbms_output.put_line("@final");
        
          --execute
          execute immediate "@final";
        end;
        

        --oracle 不喜欢 @ 符号,如果你改变它:

        declare
        vselect varchar(200) := 'select * ';
        vfrom varchar(200) := ' from table ';
        vwhere varchar(200) := ' where 1=1';
        vfinal varchar(200) :=vselect||vfrom||vwhere;
        begin
          --test result string
          --dbms_output.put_line(vfinal);
        
          --execute
          execute immediate vfinal;
        end;
        

        附言dbms_sql 与立即执行之间的区别请参见此处 ask tom dbms_sql vs execute immediate

        【讨论】:

        • T-SQL 需要@ 来标识变量。这不是名字的一部分。 SQL Server 显然需要这个来区分变量引用和例如列名。
        【解决方案4】:

        您的 Oracle 过程如下所示:

        declare
          v_where varchar2(200);
          v_select varchar2(200);
          v_from varchar2(200);
          v_final varchar2(600);
        begin
          v_select := 'select * ';
          v_from := 'from table ';
          v_where := 'where 1 = 1';
          v_final := v_select || v_from || v_where;
        end;
        /
        

        注意我已将变量更改为以“v_”而不是“@”开头,因为 Oracle 不喜欢以非字母字符开头的标识符,还因为只保留“@”可能会混淆代码,因为select、from 和 where 是保留字。

        还请注意,我已将 v_final 变量的长度扩展到 600,因为前面的 3 个字符串每个可能是 200 个字符,而 200*3 不适合 200 个字符!

        我已排除运行查询,因为您没有说明您需要用它做什么。在 Oracle 中,如果您在 PL/SQL 中运行 select 语句,则需要将结果存储在某处。这可能是将它们批量收集到一个集合中,或者循环遍历结果并将每一行存储在一个记录或一组变量中。

        或者您可以简单地将查询作为引用游标传递回调用代码,然后允许调用代码从查询中取回结果,就好像它直接运行了 sql 一样。

        简而言之,如果您想知道如何在 pl/sql 中运行 select 语句,您需要提供更多信息,说明您接下来将如何使用它。你在某处插入吗?更新什么?等等

        【讨论】:

        • 我想选择一些东西。我也想要动态 sql,所以我需要合并/加入局部变量
        • 但是一旦您完成了选择,您将如何处理数据?
        • 还有什么叫这个程序?它是临时的东西,还是您将要放入存储过程的东西?使用完全动态的 sql 可能会有点痛苦 - 如果您不知道可能会返回哪些列并且您需要在 PL/SQL 中访问所述列,那么您将无法使用本机动态 sql(又名execute immediate)。相反,您将不得不使用 dbms_sql 包中的过程来处理查询。但是,根据您对查询的处理方式,这可能是多余的。
        • execute immediate动态sql,然后将结果返回到局部变量是一种正常的做法,例如EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;
        • dbms_sql vs execute immediate - 太宽泛的问题,讨论这里是asktom.oracle.com/pls/apex/…
        【解决方案5】:

        使用 concat 函数或 concat 运算符 (||)oracle

        DECLARE
          v_where  VARCHAR2(200);
          v_Select VARCHAR2(200);
          v_from   VARCHAR2(200);
          v_final  VARCHAR2(200);
          v_result VARCHAR2(200);
        BEGIN
          v_Select:='select 1 ';
          v_from  :='from dual ';
          v_where :='where sysdate=sysdate';
          v_final :=concat(concat(v_select,v_from),v_where);
        
          EXECUTE immediate v_final INTO v_result;
          dbms_output.put_line(v_result);
        END; 
        

        DECLARE
          v_where  VARCHAR2(200);
          v_Select VARCHAR2(200);
          v_from   VARCHAR2(200);
          v_final  VARCHAR2(200);
          v_result VARCHAR2(200);
        BEGIN
          v_Select:='select 1 ';
          v_from  :='from dual ';
          v_where :='where sysdate=sysdate';
          v_final :=(v_select||v_from||v_where);
          EXECUTE immediate v_final INTO v_result;
          dbms_output.put_line(v_result);
        END; 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-06-05
          • 2018-12-19
          • 2016-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多