在PL-SQL中的选择错误:选择之后的INTO。

20 浏览
0 Comments

在PL-SQL中的选择错误:选择之后的INTO。

我在一个测试脚本窗口中有以下查询:

声明

-- 在这里定义本地变量

p_StartDate date := to_date('10/15/2012');

p_EndDate date := to_date('10/16/2012');

p_ClientID integer := 000192;

开始

-- 在这里编写测试语句

select d.r "R",

e.amount "Amount",

e.inv_da "InvoiceData",

e.product "ProductId",

d.system_time "Date",

d.action_code "Status",

e.term_rrn "IRRN",

d.commiount "Commission",

0 "CardStatus"

from docs d

inner join ext_inv e on d.id = e.or_document

inner join term t on t.id = d.term_id

where d.system_time >= p_StartDate

and d.system_time <= p_EndDate

and e.need_r = 1

and t.term_gr_id = p_ClientID;

结束

这是错误信息:

ORA-06550: 第9行,第3列:在这个SELECT语句中需要一个INTO子句

我长期使用T-SQL,对PL/SQL还不熟悉。

这里有什么问题?

0
0 Comments

在PL/SQL中,当使用SELECT语句将数据选入变量时,需要注意一些错误,其中之一就是"INTO After SELECT"错误。这个错误的出现原因是没有为选入的数据提供存储结构。

解决这个问题的方法是使用合适的数据结构来存储选入的数据。可以使用%TYPE来声明变量,以便使用表中相应列的数据类型。另外,还可以使用%ROWTYPE来创建一个与表结构相匹配的记录类型变量。

以下是一个例子来说明如何解决这个问题:

DECLARE
  -- 声明变量
  deptid        employees.department_id%TYPE;
  jobid         employees.job_id%TYPE;
  emp_rec       employees%ROWTYPE;
  -- 创建一个类型结构
  TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
  all_emps      emp_tab;
BEGIN
  -- 选入数据到变量
  SELECT department_id, job_id INTO deptid, jobid 
     FROM employees WHERE employee_id = 140;
  IF SQL%FOUND THEN 
    DBMS_OUTPUT.PUT_LINE('Dept Id: ' || deptid || ', Job Id: ' || jobid);
  END IF;
  -- 选入数据到记录类型变量
  SELECT * INTO emp_rec FROM employees WHERE employee_id = 105;
  -- 选入数据到类型结构变量
  SELECT * INTO all_emps FROM employees;
  DBMS_OUTPUT.PUT_LINE('Number of rows: ' || SQL%ROWCOUNT);
END;
/

在这个例子中,我们首先声明了变量deptid和jobid,它们的数据类型与employees表中的department_id和job_id列相匹配。然后,我们使用SELECT语句将这些列的值选入这些变量中。

接下来,我们声明了一个记录类型变量emp_rec,它的结构与employees表的结构相匹配。然后,我们使用SELECT * INTO语句将employees表中employee_id为105的数据选入emp_rec变量中。

最后,我们声明了一个类型结构emp_tab,并使用SELECT * INTO语句将整个employees表的数据选入all_emps变量中。

通过使用合适的数据结构,我们可以避免"INTO After SELECT"错误,并成功将选入的数据存储在变量中。

0
0 Comments

问题原因:

在PL-SQL语言中,SELECT语句在执行时,通常会将结果保存到一个游标或变量中。然而,在这个例子中,SELECT语句没有指定将结果保存到哪个变量中,而是直接使用了dbms_output.put_line函数将结果输出到屏幕上。这样的用法是错误的,因为在SELECT语句之后使用INTO子句来将结果保存到变量中。

解决方法:

要解决这个问题,需要将SELECT语句修改为将结果保存到一个变量中,然后再使用dbms_output.put_line函数将变量的值输出到屏幕上。修改后的代码如下:

set serveroutput on
declare
  -- Local variables here
  p_StartDate date := to_date('10/15/2012');
  p_EndDate   date := to_date('10/16/2012');
  p_ClientID  integer := 000192;
  -- 新增变量
  v_R          docs.r%type;
  v_Amount     ext_inv.amount%type;
  v_InvoiceData ext_inv.inv_da%type;
  v_Product    ext_inv.product%type;
  v_Date       docs.system_time%type;
  v_Status     docs.action_code%type;
  v_IRRN       ext_inv.term_rrn%type;
  v_Commission docs.commiount%type;
  v_CardStatus integer;
begin
  for cur in ( select d.r                          "R",
                      e.amount                     "Amount",
                      e.inv_da                     "InvoiceData",
                      e.product                    "ProductId",
                      d.system_time                "Date",
                      d.action_code                "Status",
                      e.term_rrn                   "IRRN",
                      d.commiount                  "Commission",
                      0                            "CardStatus"
                 from docs d
                 inner join ext_inv e on d.id = e.or_document
                 inner join term t on t.id = d.term_id
                 where d.system_time >= p_StartDate
                   and d.system_time <= p_EndDate
                   and e.need_r = 1
                   and t.term_gr_id = p_ClientID)
   LOOP
       -- 修改赋值语句
       v_R          := cur.R;
       v_Amount     := cur.Amount;
       v_InvoiceData:= cur.InvoiceData;
       v_Product    := cur.ProductId;
       v_Date       := cur.Date;
       v_Status     := cur.Status;
       v_IRRN       := cur.IRRN;
       v_Commission := cur.Commission;
       v_CardStatus := cur.CardStatus;
       
       dbms_output.put_line('R: '||v_R||'Amount:  '||v_Amount/*...*/);
   END LOOP;
end;
/

0
0 Comments

问题原因:这个问题的出现是因为在PL-SQL中,SELECT语句执行后,不能直接使用INTO子句将结果集赋值给变量。

解决方法:要解决这个问题,可以使用以下两种方法:

1. 使用sqlplus或plsql developer的"command window"或"sql window",并使用参数查询的SELECT语句。在执行查询时,系统会提示输入参数的值。

示例代码如下:

select d.r                          "R",
       e.amount                     "Amount",
       e.inv_da                     "InvoiceData",
       e.product                    "ProductId",
       d.system_time                "Date",
       d.action_code                "Status",
       e.term_rrn                   "IRRN",
       d.commiount                  "Commission",
       0                            "CardStatus"
from docs d
inner join ext_inv e on d.id = e.or_document
inner join term t on t.id = d.term_id
where d.system_time >= &p_StartDate
  and d.system_time <= &p_EndDate
  and e.need_r = 1
  and t.term_gr_id = &p_ClientID;

2. 如果要在PL-SQL中使用,可以使用显式游标来解决。在PL-SQL代码中声明一个游标变量,并将查询结果赋值给该变量。

示例代码如下:

declare

-- 声明局部变量

p_StartDate date := to_date('10/15/2012');

p_EndDate date := to_date('10/16/2012');

p_ClientID integer := 000192;

-- 声明游标变量

src SYS_REFCURSOR;

begin

-- 执行查询并将结果赋值给游标变量

OPEN :src FOR select d.r "R",

e.amount "Amount",

e.inv_da "InvoiceData",

e.product "ProductId",

d.system_time "Date",

d.action_code "Status",

e.term_rrn "IRRN",

d.commiount "Commission",

0 "CardStatus"

from docs d

inner join ext_inv e on d.id = e.or_document

inner join term t on t.id = d.term_id

where d.system_time >= p_StartDate

and d.system_time <= p_EndDate

and e.need_r = 1

and t.term_gr_id = p_ClientID;

end;

需要注意的是,在代码中需要添加一个名为"src"、类型为"cursor"的变量,运行PL-SQL代码后,该变量将保存结果集。

0