在PL-SQL中的选择错误:选择之后的INTO。
在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还不熟悉。
这里有什么问题?
在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"错误,并成功将选入的数据存储在变量中。
问题原因:
在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; /
问题原因:这个问题的出现是因为在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代码后,该变量将保存结果集。