尝试在存储过程中创建临时表

时间:2015-11-22 21:57:03

标签: oracle plsql

我正在尝试在存储过程中创建并填充临时表。但它会抛出错误

  

在期待其中一个

时遇到符号“DECLARE”

这是我的代码。

CREATE OR REPLACE PROCEDURE pro_print_borrower
IS
days number := 0


DECLARE LOCAL TEMPORARY TABLE temp(Borrower_name varchar2(30) NOT NULL, Book_Title number NOT NULL, less_than equal_5days number,
    less_than equal_10days number,less_than equal_15days number,more_than_15days number)
on commit delete rows;

FOR O IN (SELECT BO.name , B.book_title, (current_date - I.issue_date) INTO days
          FROM Borrower BO,Issue I,Books B
          WHERE B0.borrower_id = I.borrower_id AND I.book_id = B.book_id;)

    IF (days <= 5) THEN
        INSERT INTO temp values(O.name,O.book_title,O.days,NULL,NULL,NULL);
    ELSIF(days <=10)
        INSERT INTO temp values(O.name,O.book_title,NULL,O.days,NULL,NULL);
    ELSIF(days <= 15)
        INSERT INTO temp values(O.name,O.book_title,NULL,NULL,O.days,NULL);
    ELSIF(days>15)
        INSERT INTO temp values(O.name,O.book_title,NULL,NULL,NULL,O.days);
    END IF;

END LOOPS;

SELECT *
FROM temp;

END ;

.
run;

2 个答案:

答案 0 :(得分:2)

这似乎是尝试将MS T-SQL转换为Oracle PL / SQL。临时表在Oracle中不像那样工作,但无论如何通常都不需要它们。

在纯Oracle SQL中实现逻辑非常简单,使用子查询因子子句(MSSQL术语中的公用表表达式),然后使用CASE语句切换DAYS值的列。

with cte as (select bo.name 
                     , b.book_title
                     , (current_date - i.issue_date) as days
              from borrower bo,
                      issue i,
                      books b
              where b0.borrower_id = i.borrower_id 
              and i.book_id = b.book_id)
select cte.name as borrower_name
        , cte.book_title
        , case when (cte.days <= 5) then cte.days end as less_than equal_5days
        , case when (cte.days > 5 and cte.days <= 10) then cte.days end as less_than equal_10days
        , case when (cte.days > 10 and cte.days <= 15) then cte.days end as less_than equal_15days
        , case when (cte.days > 15) then cte.days end as more_than_15days
from cte
;
  

&#34;只需在屏幕上显示&#34;

因此,要向屏幕显示内容,我们可以使用DBMS_OUTPUT并从SQL * Plus或TOAD等交互式客户端调用代码。 Find out more

所以在你的情况下我们可以像这样运行一个匿名块:

begin
    for rec in (
    with cte as (select bo.name 
                         , b.book_title
                         , (current_date - i.issue_date) as days
                  from borrower bo,
                          issue i,
                          books b
                  where b0.borrower_id = i.borrower_id 
                  and i.book_id = b.book_id)
    select cte.name as borrower_name
            , cte.book_title
            , case when (cte.days <= 5) then cte.days end as less_than equal_5days
            , case when (cte.days > 5 and cte.days <= 10) then cte.days end as less_than equal_10days
            , case when (cte.days > 10 and cte.days <= 15) then cte.days end as less_than equal_15days
            , case when (cte.days > 15) then cte.days end as more_than_15days
    from cte
    )
    loop
         dbms_output.put_line(rec.borrower_name
                              ||' '||rec.book_title
                              ||' '||lpad(to_char( rec.less_than equal_5days ), 6)
                              ||' '||lpad(to_char( rec.less_than equal_10days ), 6)
                              ||' '||lpad(to_char( rec.less_than equal_15days ), 6)
                              ||' '||lpad(to_char( rec.more_than_15days ), 6)
                          );
    end loop;
end;
/

答案 1 :(得分:0)

不确定是否会使用该语言来询问此代码。根据问题,它不是纯粹的Oracle。但仍然尝试修改你的代码,并根据要求为你提供工作代码IN ORACLE。让我知道下面的代码是否有帮助。

        CREATE OR REPLACE PROCEDURE pro_print_borrower
        IS
          days PLS_INTEGER := 0;
          lv_create_table_sql LONG;
          p_lst sys_refcursor;
        BEGIN

-- Why to create dynamically. Create it once and use it.

          lv_create_table_sql:= ' CREATE GLOBAL TEMPORARY TABLE temp    
                                  (Borrower_name VARCHAR2(30) NOT NULL,     
                                  Book_Title NUMBER NOT NULL,     
                                  less_than equal_5days NUMBER,     
                                  less_than equal_10days NUMBER,    
                                  less_than equal_15days NUMBER,    
                                  more_than_15days NUMBER    
                                  ) ON COMMIT    
                                  DELETE ROWS ';

    EXECUTE IMMEDIATE lv_create_table_sql;

          FOR O IN
          (SELECT BO.name ,
            B.book_title,
            (CURRENT_DATE - I.issue_date)
          FROM Borrower BO,
            Issue I,
            Books B
          WHERE B0.borrower_id = I.borrower_id
          AND I.book_id        = B.book_id
          )
          LOOP
            IF (days <= 5) THEN
              INSERT INTO temp VALUES
                (O.name,O.book_title,O.days,NULL,NULL,NULL
                );
            ELSIF(days <=10) THEN
              INSERT INTO temp VALUES
                (O.name,O.book_title,NULL,O.days,NULL,NULL
                );
            ELSIF(days <= 15) THEN
              INSERT INTO temp VALUES
                (O.name,O.book_title,NULL,NULL,O.days,NULL
                );
            ELSIF(days>15) THEN
              INSERT INTO temp VALUES
                (O.name,O.book_title,NULL,NULL,NULL,O.days
                );
            END IF;
          END LOOP;
          OPEN p_lst FOR SELECT * FROM TEMP;
        END ;