【问题标题】:plsql cursor via straight sql通过直接 sql 的 plsql 光标
【发布时间】:2010-11-17 17:00:25
【问题描述】:

我正在研究以下两种检索值并稍后通过插入语句存储它的方法。即通过 Pl/SQL 游标或通过直接 SQL。 这两种方法有什么优势吗?还是有更有效的方法?

方法 1

Cursor system_date
Is 
 select sysdate from dual;
system_date_rec system_date%type;

Open system_Date;
Fetch system_date into system_date_rec;

Insert into table(dateValue)
values(system_date_rec.date);

方法二

dateString  varchar(20);
Select sysdate into dateString from dual;
Insert into table(dateValue)
values(dateString);

【问题讨论】:

    标签: oracle plsql plsqldeveloper


    【解决方案1】:

    方法3怎么样:

    Insert into table(dateValue)
    values(sysdate);
    

    或者假设您确实需要进行选择来获取数据:

    Insert into table(dateValue)
    select dateValue from other_table where ...;
    

    关于当需要一个或另一个时显式游标或 SELECT INTO 是否更可取,我会选择 SELECT INTO,因为如果您希望查询只返回一行,它会更简洁、更安全:

    select some_value
    into l_var
    from other_table
    where ...;
    
    if l_var = 'A' then
      do_something;
    end if;
    

    现在,如果返回的行数与预期不符,您将收到异常(NO_DATA_FOUND 或 TOO_MANY_ROWS)。使用游标,你最终会得到 l_var 不变,或者设置为第一个匹配行的值 - 这可能意味着你有一个错误但不知道。

    【讨论】:

    • “sysdate”只是演示这些方法的一个例子,但它并不是我真正想做的。我只是想知道这两种方法中哪一种在性能方面更有效。我有时必须编写几个大查询并通过访问游标或局部变量来处理结果。您知道这两种方法之间是否会有任何性能差异?谢谢:)
    • 我相信 SELECT INTO 会稍微快一点。
    • 每次回看这个答案都比上次长!
    • 我知道,在思考蹄子!
    【解决方案2】:

    每种方法都有其优点,但如果它是您获得的唯一一个值,那么我会选择select ... into ...,因为这更简单,并且会检查您是否只有一个值。

    尽管在适当的情况下,Tony 的方法可能比两者都更可取。

    如果您还想取回该值,则插入语句的 RETURNING 子句始终存在。

    my_date_value date;
    ...
    INSERT into table(datevalue)
    values (sysdate)
    returning sysdate into my_date_value;
    

    【讨论】:

    • 有趣,我不知道 insert 有一个返回子句。
    【解决方案3】:

    我同意@Tony 和@MikeyByCrikey 的观点,即select ... into 通常更可取,尤其是-在我个人的主观意见中-因为它使选择和进入保持在一起,而不是让选择在声明部分。如果它很简单,这并不是一个真正的问题,但您建议您正在执行几个大型查询和操作,这意味着一个冗长的过程。

    有点题外话,但如果所有操作都是在最后为单个插入收集数据,那么我会考虑将单个变量声明为行类型并将列更新为适当的:

    declare
        l_row my_table%ROWTYPE;
    begin
        select ... into l_row.column1;
        select ... into l_row.column2;
        if l_row.column2 = 'A' then
            /* do something */
        end if;
        l_row.column3 := 'somevalue';
        fetch ... into l_row.column4;
        /* etc */
        insert into my_table values l_row;
    end;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多