【问题标题】:How to "scale" scripts with substitution variables using loops?如何使用循环“缩放”带有替换变量的脚本?
【发布时间】:2016-06-30 11:32:49
【问题描述】:

我经常在我的脚本中使用替换变量来避免重复内容:

select count(*) from &&my_table;
select * from &&my_table;
-- etc.
-- a ton more queries here that are used often in together to check and run things

在哪里:

define my_table = 'dual'; -- bad example

但是当我切换到另一个流时(因为另一个表成为我查询的中心点),我经常不得不更改 my_table

我可以为变量创建这些类型的数组吗? (显然,我四处搜索并没有找到方法,但是 我能做些什么来循环遍历一组值,在我的情况下是表名,填写变量中的每个表并再次运行所有查询,又一次?

【问题讨论】:

  • 使用batch fileunix script 循环遍历您的数组并调用您的SQL script with parameters
  • @Motor 我需要在 SQL Developer 中查看结果或其他内容,而不是一劳永逸
  • 然后将脚本输出重定向到一个文件,并在您想要查看该文件时查看该文件。
  • 老兄,我想在 ide 的表格视图中查看结果

标签: oracle plsql


【解决方案1】:

我可以为变量创建这些类型的数组吗?

是的,使用 Oracle 的集合类型:

DEFINE
  TYPE table_name_table IS TABLE OF VARCHAR2(30);
  table_names  table_name_table := table_name_table( 'TABLE1', 'TABLE2', 'DUAL' );
  my_table VARCHAR2(30);
BEGIN
  FOR i IN 1 .. table_names.COUNT LOOP
    my_table := table_names(i);
    -- process your script...
  END LOOP;
END;
/

【讨论】:

  • 你没有抓住重点。您的解决方案中定义的替换变量在哪里?你不能这样做:从 my_table 中选择 count(1)
  • 是的,您可以使用动态 sql 和绑定变量。 sql := '选择 count(*) 到 :1 from' ||我的表;使用 myCountVar 立即执行 sql;
  • 那不是绑定变量。这是一个正常的变量
【解决方案2】:

我猜你想使用动态 sql 来替换表名。

https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011

【讨论】:

  • 如果可能的话,我想避免代码生成和“执行”命令。到目前为止,替换变量一直很好,但我想进一步改进我的脚本(我想循环)
  • 您不必进行代码生成,只需使用表名作为参数来调用 PL/SQL 包/过程。
  • @Belun 使用执行命令没有任何问题。它的存在是因为您想要在您的问题中实现的目标。
  • 我必须自己输出文本。如果我进行选择,我必须输出结果。我不想要这个。我想在 ide (oracle sql developer) 必须提供的漂亮的表视图中进行选择。
【解决方案3】:

不完全确定您想要做什么,但是 SQL*Plus 中没有一个简单的结构可以做到这一点。您可以做的最接近的方法如下:

为给定表运行查询的 worker.sql 脚本:

define &tabname='&1'

PROMPT &tabname

SELECT count(1) FROM &tabname;

接下来是 gendriver.sql 脚本以接受您的表列表并驱动工作脚本:

ACCEPT tablist CHAR PROMPT 'Enter table comma separated list: '

spool driver.sql
SET SERVEROUTPUT ON
set feedback off
set verify off
DECLARE
   L_TABLE        DBMS_UTILITY.UNCL_ARRAY;
   L_TABLELEN     BINARY_INTEGER;
BEGIN
   DBMS_UTILITY.COMMA_TO_TABLE ('&tablist', L_TABLELEN, L_TABLE);
   FOR I IN L_TABLE.FIRST .. L_TABLE.LAST
   LOOP
      IF l_table(i) IS NOT NULL THEN
         DBMS_OUTPUT.PUT_LINE( '@worker.sql ' || l_table(i) );
      END IF;
   END LOOP;
END;
/
spool off

运行方式并输入逗号分隔的表格列表,例如:

Enter table comma separated list: tab1, tab2, tab3, tab4

生成的 driver.sql 脚本将如下所示:

@worker.sql tab1
@worker.sql  tab2
@worker.sql  tab3
@worker.sql  tab4

然后运行 ​​driver.sql

@driver.sql

【讨论】:

    【解决方案4】:

    SQLPlus 中没有循环命令。要填充变量,您可以使用以下内容:

    SET verify OFF
    column t1 new_value tname1
    column t2 new_value tname2
    select &table_name from dual;
    -- Your script
    select count(*) from &&tname1;
    select * from &&tname1;
    -- Your script again
    select count(*) from &&tname2;
    select * from &&tname2;
    

    然后使用 "'dual' t1, 'dual' t2" 作为 table_name 参数的值。

    是的,我知道这不是解决方案。我不明白你想要达到什么目的。如果要对不同的表执行相同的命令集,请在 SQL Developer 中使用带有变量或占位符的 SQL 编辑器代码模板,或者对不同的流使用不同的代码段。如果您想要报告,请使用 PL/SQL、动态 sql、管道函数、脚本生成。

    【讨论】:

      猜你喜欢
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-25
      • 2023-04-08
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      相关资源
      最近更新 更多