关于oracle循环语句的一个问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于oracle循环语句的一个问题相关的知识,希望对你有一定的参考价值。
表A有列1,列2两个字段
表B有列3
我想把表A的两列数据放进这语句:
update 表B set 列3 = (列1数据) where 列3 = (列2数据)
用什么样的语句让它执行完表A里面的所有数据去更改表B的数据?
那个语句可以用其他语句代替,这个语句只是我想实现那个效果
(select 列1 from table_A a where b.列3=a.列2 and rownum=1)
where exists(select 1from table_A c where a.列3=c.列2);
这是一种办法。。。
或者使用游标
create or replace procedure pro_test as
cursor cur_test is select 列1,列2 from table_A,table_B where table_A.列2=table_B.列3;
begin
for I in cur_test loop
update table_B set 列3=I.列1 where 列3=I.列2;
end loop;
end;
/
exec pro_test;
这样回答可以解决你的疑问么? 参考技术A 一条SQL即可搞定!
update 表B,表A set 表B.列3 = 表A.列1 where 表B.列3 = 表A.列2 参考技术B update B set 列3=A.列1(或者2) from A
where A.xx=b.xx 参考技术C 请问是一个语句还是一个过程?
如何在 Oracle 循环中的 select 语句中执行 alter 命令?
【中文标题】如何在 Oracle 循环中的 select 语句中执行 alter 命令?【英文标题】:How to execute alter command within select statement in a loop in Oracle? 【发布时间】:2020-10-24 13:16:58 【问题描述】:我正在尝试通过脚本重建模式的索引,但我被困在通过 select 语句获取字符串 ALTER INDEX OWNER.INDEX_NAME REBUILD NOLOGGING 但我不知道如何执行更改命令的地方,请指南:
我尝试将第二个 for 循环中使用的 select 查询的值分配给 str,然后执行它,但它给出了错误。
IS
STR VARCHAR2(5000);
BEGIN
FOR T IN (
SELECT USERNAME FROM DBA_USERS WHERE USERNAME ='REPORT'
)
LOOP
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING; ' FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
LOOP
--- EXECUTE IMMEDIATE STR ;
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
COMMIT;
END LOOP;
END LOOP;
END ;
【问题讨论】:
【参考方案1】:您使用动态 sql。而且你不需要你的外循环。 dba_indexes 中提供了该过滤器:
create procedure bld_idx
is
vsql varchar2(500);
for x in (select owner,
index_name
from dba_indexes
where owner = 'REPORT'
and TEMPORARY='N'
)
loop
vsql := ' ALTER INDEX '||x.OWNER||'.'||x.INDEX_NAME|| ' REBUILD NOLOGGING; ';
dbms_output.put_line(vsql); -- debugging only
execute immediate vsql;
end loop;
end;
注 1:上面是我的头顶。可能存在轻微的语法问题,但如果是这样,您应该能够解决它们。
不是 2:重建索引不是正常情况下需要做的事情。 Richard Foote 可能是预言机索引内部最重要的权威,他有话要说:https://richardfoote.wordpress.com/2007/12/11/index-internals-rebuilding-the-truth/
【讨论】:
我写了你的脚本,但我收到 ORA-02243 错误:“无效的 ALTER INDEX 或 ALTER MATERIALIZED VIEW 选项” *原因:在 ALTER INDEX 中指定了除 INITRANS、MAXTRANS 或 STORAGE 以外的选项语句或 ALTER MATERIALIZED VIEW 语句的 USING INDEX 子句中。 *行动:仅指定合法选项。 好吧,我确实说过这不是我的想法,可能存在一些语法问题。去除那个 ';'从带引号的字符串内部构建 ALTER 语句。老实说,我也花了一点时间才发现它。执行动态 sql 时,我们不需要(或不想要!)终止分号作为字符串的一部分。 顺便说一句,我写了我之前的回复,以及我实际的编码答案,只是为了帮助你学习编写更好的 PL/SQL 我希望两次被引用的 Richard Foote 文章已经让你相信特定的程序是浪费时间。【参考方案2】:“它给出了错误。”如果没有您收到的实际错误,将无济于事。那就是说你犯了很多其他人犯的同样的错误,你不应该包括“;”作为动态 SQL 的一部分 - 它不是语句的一部分,它仅由您的客户端用于了解何时将代码发送到数据库。
FOR CUR IN
(
SELECT ' ALTER INDEX '||OWNER||'.'||INDEX_NAME|| ' REBUILD NOLOGGING' ddl_cmd FROM DBA_INDEXES
WHERE OWNER=T.USERNAME AND TEMPORARY='N'
)
...
EXECUTE IMMEDIATE CUR.ddl_cmd ;
(我还为该列指定了一个别名,以便您可以在循环中很好地使用它。
然后
INSERT INTO INDEX_REBUILD_HISTORY
SELECT DISTINCT OWNER, TRUNC(LAST_DDL_TIME) from DBA_OBJECTS where OBJECT_TYPE = 'INDEX'
AND
OWNER=T.USERNAME ;
没有过滤您刚刚重建的索引,它似乎不会获得完全有用的信息。
也就是说…… 离线重建所有索引并使其无法恢复真的值得吗?可能不会,如果您不止一次这样做并且从中受益,那么您的数据模型可能会有所改变以提供帮助。好好阅读 Richard Foote 的这篇演讲,他是一位知名的 Oracle 索引专家 https://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf 我怀疑您是否会相信重建所有索引是一种解决方案。
【讨论】:
看来我们俩同时写了我们的回复!我希望我们都引用了相同的 Richard Foote 帖子这一事实不会在 OP 中丢失! :-)以上是关于关于oracle循环语句的一个问题的主要内容,如果未能解决你的问题,请参考以下文章