sql - 在 for 循环中选择语句
问题描述
我试图将我的 select 语句放在一个 for 循环中,循环后我想将结果插入到一个表中,但是在我执行时我遇到了这个错误。
ORA-06550:第 5 行,第 7 列:
PLS-00428:此 SELECT 语句中需要一个 INTO 子句
所以我的查询是这样的。循环后,我想将结果插入表中。
BEGIN
for cur_rec in (Select Distinct SDESCRIPTION from TB_READER where SDESCRIPTION is not null and SDESCRIPTION not Like '%IN%' and SDESCRIPTION not like '%OUT%')
loop
SELECT L.NEVENTLOGIDN, LPAD (nuserid, 6, '0') nuserid, u.susername,
TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS')
date_time, l.nreaderidn, r.sname,
CASE WHEN l.nreaderidn IN (SELECT nreaderidn FROM tb_reader where sdescription = cur_rec.SDESCRIPTION and upper(sname) like '%' || upper('OUT') || '%') THEN 'OUT'
WHEN l.nreaderidn IN (SELECT nreaderidn FROM tb_reader where sdescription = cur_rec.SDESCRIPTION and upper(sname) like '%' || upper('IN') || '%') THEN 'IN' END logtype
FROM TB_EVENT_LOG l, TB_READER r, TB_USER u
WHERE
l.nreaderidn IN (SELECT nreaderidn FROM tb_reader where sdescription = cur_rec.SDESCRIPTION)
AND NDATETIME >= (trunc(sysdate -1) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND ndatetime <= (trunc(sysdate) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND l.nuserid = u.suserid
AND l.nreaderidn = r.nreaderidn
ORDER BY 2, 4;
end loop;
END;
/
解决方案
BEGIN ... END;
代码块通常称为“匿名块” 。
在这里重要的是要理解,这不仅仅是完全普通的代码SQL
,而是PL/SQL
代码,即在这个块中您正在编写过程代码(PL/SQL 代表 SQL 的过程语言)。
当您执行简单的 SQL 查询(例如SELECT columns FROM table
在匿名块之外)时,数据库引擎会将来自该查询的数据返回到您用来执行它的工具。但是在这里您正在编写代码(恰好包括 SQL),当它执行时,该查询的结果会去哪里?程序如何知道将这些结果发送到哪里?
虽然很大一部分PL/SQL
涉及编写SQL
然后执行一些其他任务,并且在许多情况下它是同义词,SQL
因为许多关键字和内置函数具有相同的名称,但值得牢记的是PL/SQL
,SQL
它们是两个不同的环境并且工作轻微不同。
您可以看到错误消息的区别:ORA-#####
来自数据库引擎,而PLS-#####
来自 PL/SQL 引擎。
无论如何,我希望这些背景信息对您有所帮助。您遇到的具体问题是您的程序不知道将查询的输出存储在哪里,因此您需要定义一些局部变量,然后将SELECT
语句的结果存储在INTO
这些局部变量中。使用SELECT ... INTO
语句时,您需要确保只返回一行,否则会得到不同的错误。(如果您的语句可能返回多行,则可以使用游标,那么您也将有一个内部循环)。
DECLARE
/* apologies for the quick and dirty example here;
* you'd want to use better variable names and correct data types and lengths
*/
s1 VARCHAR2(100 CHAR);
s2 VARCHAR2(100 CHAR);
s3 VARCHAR2(100 CHAR);
s4 VARCHAR2(100 CHAR);
s5 VARCHAR2(100 CHAR);
s6 VARCHAR2(100 CHAR);
s7 VARCHAR2(100 CHAR);
BEGIN
for cur_rec in (Select Distinct SDESCRIPTION
from TB_READER
where SDESCRIPTION is not null
and SDESCRIPTION not Like '%IN%'
and SDESCRIPTION not like '%OUT%')
loop
SELECT L.NEVENTLOGIDN,
LPAD (nuserid, 6, '0') nuserid,
u.susername,
TO_CHAR (TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + ( (ndatetime) / (60 * 60 * 24)), 'YYYY-MM-DD HH24:MI:SS') date_time,
l.nreaderidn,
r.sname,
CASE WHEN l.nreaderidn IN (SELECT nreaderidn
FROM tb_reader
where sdescription = cur_rec.SDESCRIPTION
and upper(sname) like '%' || upper('OUT') || '%') THEN 'OUT'
WHEN l.nreaderidn IN (SELECT nreaderidn
FROM tb_reader
where sdescription = cur_rec.SDESCRIPTION
and upper(sname) like '%' || upper('IN') || '%') THEN 'IN' END logtype
INTO s1, s2, s3, s4, s5, s6, s7
FROM TB_EVENT_LOG l, TB_READER r, TB_USER u
WHERE l.nreaderidn IN (SELECT nreaderidn
FROM tb_reader
where sdescription = cur_rec.SDESCRIPTION)
AND NDATETIME >= (trunc(sysdate -1) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND ndatetime <= (trunc(sysdate) - TO_DATE ('1970-01-01 12:00:00 AM', 'YYYY-MM-DD HH:MI:SS AM')) * 24 * 60 * 60
AND l.nuserid = u.suserid
AND l.nreaderidn = r.nreaderidn
ORDER BY 2, 4;
end loop;
END;
/
推荐阅读
- javascript - React:将 2 个 props 从子组件传递回同一函数中的父组件
- mysql - 分组总和摘要
- javascript - 将文件引用添加到数据库中
- javascript - 在 Fabric JS 中更改活动对象的边框颜色和样式
- python - 如何让python忽略垃圾收集的对象?
- ms-access - 使用 pdf 文件路径在 Ms Access Report 中显示 Pdf 预览
- java - 将 spring boot 从 1.3.5 更新到 1.5.17 后找不到 log4j 库
- ms-access - 在 Access 报告中显示链接的图像
- lua - 使用 Lua 在一行中读取多个值
- javascript - 使用Javascript的简单数字猜谜游戏