【问题标题】:LOOP/FOR statement on oracle scriptoracle 脚本上的 LOOP/FOR 语句
【发布时间】:2021-04-18 18:42:48
【问题描述】:

我正在运行一个 ansible playbook,它将 sqlplus 脚本运行到 Oracle DB。
基本上,该脚本会创建一个包含一些服务器信息的 CSV 文件。查询几乎是自动生成的,因此很难更改它。

set markup csv on
spool 'playbook-dir/files/servers.csv'

SELECT *
FROM   (SELECT DISTINCT server.primary_name                  SERVER_NAME,
                        server.arpa_domain                   ARPA_DOMAIN,
                        server.impact                        IMPACT,
                        instance_definition.category         SOLUTION_CATEGORY,
                        instance_definition.instance_name    SOLUTION_NAME,
                        instance_on_server.ins_instance_name INSTANCE_NAME
        FROM   server_db.instance_definition, server_db.instance_on_server, server_db.business, server_db.server_customer, server_db.server
        WHERE  ( server_db.instance_definition.app_id(+) = server_db.instance_on_server.app_id )
               AND ( server_db.server.system_id = server_db.instance_on_server.system_id(+) )
               AND ( ( instance_definition.instance_name LIKE '%windows%' )
                      OR ( instance_definition.instance_name LIKE '%centos%' ) )
               AND ( instance_on_server.status LIKE 'in production' )
               AND ( server_db.business.business_id(+) = server_db.server_customer.business_id )
               AND ( server_db.server_customer.system_id(+) = server_db.server.system_id )
               AND (( instance_definition.category LIKE 'os' ))
               AND (( server.primary_name||'.'||server.arpa_domain LIKE '%' ))
               AND business.secure_access_r <> 1)
WHERE  ROWNUM <= 600000 + 1
ORDER  BY server_name;  

spool off

问题是这个查询带来了所有 5000 台服务器,而我只需要 200 台。
我想添加一个仅包含我需要的服务器的 LOOP/FOR 语句,但我认为我做错了什么。
这是带有 LOOP 的查询:

declare
  type table_varchar  is table of varchar2(10);

  var_table_varchar  table_varchar;
begin
  var_table_varchar  := table_varchar('server1', 'server2', 'server3', 'server4');

  for elem in 1 .. var_table_varchar.count loop
    SELECT *
    FROM   (SELECT DISTINCT server.primary_name                  SERVER_NAME,
                            server.arpa_domain                   ARPA_DOMAIN,
                            server.impact                        IMPACT,
                            instance_definition.category         SOLUTION_CATEGORY,
                            instance_definition.instance_name    SOLUTION_NAME,
                            instance_on_server.ins_instance_name INSTANCE_NAME
            FROM   server_db.instance_definition, server_db.instance_on_server, server_db.business, server_db.server_customer, server_db.server
            WHERE  ( server_db.instance_definition.app_id(+) = server_db.instance_on_server.app_id )
                   AND ( server_db.server.system_id = server_db.instance_on_server.system_id(+) )
                   AND ( ( instance_definition.instance_name LIKE '%windows%' )
                          OR ( instance_definition.instance_name LIKE '%centos%' ) )
                   AND ( instance_on_server.status LIKE 'in production' )
                   AND ( server_db.business.business_id(+) = server_db.server_customer.business_id )
                   AND ( server_db.server_customer.system_id(+) = server_db.server.system_id )
                   AND (( instance_definition.category LIKE 'os' ))
                   AND (( server.primary_name||'.'||server.arpa_domain LIKE '%' ))
                   AND (( server.primary_name LIKE '%var_assoc_varchar(elem)%' ))
                   AND business.secure_access_r <> 1)
    WHERE  ROWNUM <= 600000 + 1
    ORDER  BY server_name; 
  end loop;
end;

当我运行它时,我得到了这个错误:

错误报告 -
ORA-06550:第 9 行,第 5 列:
PLS-00428:此 SELECT 语句中需要一个 INTO 子句
06550. 00000 - “第 %s 行,第 %s 列:\n%s”
*原因:通常是 PL/SQL 编译错误。
*行动:

遗憾的是,我不是一名 DBA,而且我的知识让我走到了这一步。所以建议将不胜感激

【问题讨论】:

  • 我采用了@Popeye 建议的方法,并为 300 台服务器添加了一个新条件。

标签: sql oracle loops sqlplus


【解决方案1】:

你不能在 PL/SQL 中使用没有 into 子句的普通 select sql。

您对 PL/SQL 中的查询有何期待?

您的第一个查询执行并填充了 csv,因为它是单个查询而不是匿名块。

您可以简单地将条件添加到您的第一个查询的where 子句中,如下所示:

server.primary_name in ('server1', 'server2', 'server3', 'server4')

【讨论】:

  • 该条件适用于 300 台服务器?
  • 然后在 IN 列表中添加 300 个服务器或创建具有一列的表并在该表中添加这 300 个服务器名称以在 IN (select server_name from that_temp_table) 中使用它
猜你喜欢
  • 1970-01-01
  • 2016-07-05
  • 2018-04-07
  • 2021-07-31
  • 2013-09-02
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多