首先是CTE还是变量

时间:2018-10-26 10:16:22

标签: sql oracle

因此,我试图编写一个查询,该查询将声明两个变量(“ start”和“ end”数字),然后通过循环将其插入cte,下面的start和end之间的每个值都是我到目前为止的内容,我在做傻事吗?

编辑:我正在尝试通过print语句将1-100插入cte记录每个插入内容。 我想从中获得的经验是在同一临时脚本中使用变量和CTE的经验。

    WITH growing AS 
                (
                    SELECT 1 variable
                    FROM dual
                )
DECLARE 
            Start_Point number  := 1;
            End_Point   number  := 100;
BEGIN
        LOOP
                INSERT INTO growing VALUES (Start_Point);
                Start_Point := (Start_Point + 1);
                dbms_output.put.line(Start_Point);
                IF (SELECT COUNT(variable) FROM Growing WHERE variable = End_Point) > 0  EXIT;
                END IF;
        END LOOP;
END;

2 个答案:

答案 0 :(得分:1)

这些根本不相关。

CTE附加到SELECT语句中。这是在SELECT内的 中命名子查询的一种方法。您其余的代码是脚本代码,在Oracle中称为PL / SQL。脚本代码与SELECT语句不同。

您不能插入CTE。它实际上只是子查询的简写。我推测您想要一个临时表或某种集合。如果您需要解决问题的帮助,我建议您问另一个问题,以解释您要做什么,样本数据和期望的结果。

答案 1 :(得分:1)

您不能插入CTE,也不能将PL / SQL块挂在CTE上-只能查询。 (尽管您可以将PL / SQL 嵌入到来自12c的CTE中)。

如果要生成范围内的值,则可以使用分层查询:

with growing (variable) as (
  select <start_point> + level - 1
  from dual
  connect by level <= <end_point>
)

其中<start_point><end_point>是占位符,您需要用文字值或(取决于您如何使用它)替换或绑定变量来替换它们。因此,将范围作为固定文字:

with growing (variable) as (
  select 1 + level - 1
  from dual
  connect by level <= 100
)
select * from growing;

  VARIABLE
----------
         1
         2
         3
...
        99
       100

或使用递归CTE:

with growing (variable) as (
  select <start_point> from dual
  union all
  select variable + 1
  from growing
  where variable < <end_point>
)

如此:

with growing (variable) as (
  select 1 from dual
  union all
  select variable + 1
  from growing
  where variable < 100
)
select * from growing;

  VARIABLE
----------
         1
         2
         3
...
        99
       100

如果您尝试将其与PL / SQL变量结合使用,则可以在游标循环中使用CTE,引用CTE中的本地PL / SQL变量:

set serveroutput on
declare
  start_point number := 1;
  end_point   number := 100;
begin
  for r in (
    with growing (variable) as (
      select 1 from dual
      union all
      select variable + start_point
      from growing
      where variable < end_point
    )
    select * from growing
  )
  loop
    dbms_output.put_line(r.variable);
  end loop;
end;
/

1
2
3
...
98
99

PL/SQL procedure successfully completed.

但是您确实需要将CTE用作更大查询的一部分,无论是纯SQL还是PL / SQL块的一部分。

只需在PL / SQL中打印值,就不需要CTE,只需一个简单的循环即可:

declare
  start_point number := 1;
  end_point   number := 100;
begin
  for i in start_point..end_point loop
    dbms_output.put_line(i);
  end loop;
end;
/

,但是您当然希望对生成的数字做些更有用的事情。如果您已经在架构级别创建了一个临时表,则可以将其插入(通过PL / SQL或纯SQL)。 (应该保留它们;该表是永久的,至少对于全局临时表而言是永久的; data 是临时的。Read more)。或者您可以填充表格集合,例如

declare
  type t_tab is table of number;
  tab t_tab := t_tab();
  start_point number := 1;
  end_point   number := 100;
begin
  for i in start_point..end_point loop
    dbms_output.put_line(i);
    tab.extend();
    tab(tab.count) := i;
  end loop;
end;
/

这实际上取决于您需要对生成的数字进行处理以及将其存储在任何内容中(如果有的话)。