pl/sql - 集合可以循环遍历列名吗?

2023-12-21

以下代码的输出是:

         |LAT|MISC|SID|NO
MIN_LENGTH|1|2|1|1
MAX_LENGTH|6|6|4|2

输出正如我所期望的那样,但是无论如何都可以使用索引(即j)循环遍历列而不是执行RESULTS(I)。最长长度,结果(一)。最长长度ETC ?值得关注的是,当向“R_RESULT_REC”记录添加额外的列时,需要另一个循环。

set serveroutput on
DECLARE     
  TYPE R_RESULT_REC IS RECORD
    (COL_NAME        VARCHAR2(100),
      MIN_LENGTH         NUMBER,
      MAX_LENGTH         NUMBER
      );       
  TYPE tr_RESULT IS TABLE OF R_RESULT_REC;
  RESULTS   TR_RESULT := TR_RESULT();
  v_counter NUMBER := 1;
BEGIN
  FOR J IN (SELECT DISTINCT COLUMN_NAME FROM ALL_TAB_COLUMNS 
            WHERE OWNER = 'SYSTEM'
            and TABLE_NAME = 'SPECCHAR')
  LOOP
      RESULTS.EXTEND;
      RESULTS(V_COUNTER).COL_NAME := J.COLUMN_NAME;
      EXECUTE IMMEDIATE 'SELECT MIN(LENGTH('||J.COLUMN_NAME||')),
      MAX(LENGTH('||J.COLUMN_NAME||'))
      FROM '||'SYSTEM'||'.'||'SPECCHAR' INTO 
      RESULTS(V_COUNTER).MIN_LENGTH,
      RESULTS(V_COUNTER).MAX_LENGTH; 
      V_COUNTER := V_COUNTER + 1;
  END LOOP;
     FOR I IN RESULTS.FIRST .. RESULTS.LAST LOOP
       IF I = RESULTS.LAST THEN
         DBMS_OUTPUT.PUT_LINE(RESULTS(I).COL_NAME);
       ELSIF I = RESULTS.FIRST THEN
         DBMS_OUTPUT.PUT('         |'||RESULTS(I).COL_NAME||'|');
        ELSE
         DBMS_OUTPUT.PUT(RESULTS(I).COL_NAME||'|');
       END IF ;
    END LOOP;
    FOR I IN RESULTS.FIRST .. RESULTS.LAST LOOP
       IF I = RESULTS.LAST THEN
         DBMS_OUTPUT.PUT_LINE(RESULTS(I).MIN_LENGTH);
        ELSIF I = RESULTS.FIRST THEN
         DBMS_OUTPUT.PUT('MIN_LENGTH|'||RESULTS(I).MIN_LENGTH||'|');
        ELSE
         DBMS_OUTPUT.PUT(RESULTS(I).MIN_LENGTH||'|');
       END IF ;
    END LOOP;
     FOR I IN RESULTS.FIRST .. RESULTS.LAST LOOP
       IF I = RESULTS.LAST THEN
         DBMS_OUTPUT.PUT_LINE(RESULTS(I).MAX_LENGTH);
        ELSIF I = RESULTS.FIRST THEN
         DBMS_OUTPUT.PUT('MAX_LENGTH|'||RESULTS(I).MAX_LENGTH||'|');
        ELSE
         DBMS_OUTPUT.PUT(RESULTS(I).MAX_LENGTH||'|');
       END IF ;
    END LOOP;
end;

它使用了 DBMS_SQL,所以读起来相当困难。我看到使用它的主要原因是我可以获得 SQL 语句的列式描述以及基于缓冲区而不是基于对象的获取。

它不是在处理过程中调用 DBMS_OUTPUT,而是构建一个用于输出的记录表,为了简单起见,使用关联数组。

可以进一步细化为每个函数应用一个数组或可解析的函数列表,但这似乎超出了当前的要求。如果添加新的聚合函数,则代码的性质将需要编辑。

调用概述(2c + a + s):

  • 3 loops;
    • 对列列表 (c) 进行 2 次循环,
    • 1 次循环分析函数 (a) 的数量。
  • 1 个针对表数据的 SQL 语句。

OP的调用概述(c*s + a + 1):

  • 1个循环,针对表数据执行一条sql语句每列 (c*s)
  • a+1 循环,其中 a 是解析函数的数量

测试数据:

  1  select  min(length(GP_ID)),  max(length(GP_ID)),
  2          min(length(GGP_ID)),  max(length(GGP_ID)),
  3          min(length(OBJECT_NAME)),  max(length(OBJECT_NAME))
  4*   from AMUSCH.GP
SQL> /

MIN(LENGTH(GP_ID)) MAX(LENGTH(GP_ID)) MIN(LENGTH(GGP_ID)) 
MAX(LENGTH(GGP_ID)) MIN(LENGTH(OBJECT_NAME)) MAX(LENGTH(OBJECT_NAME))
                  1                  7                   1                              
                  4                        9                       41

Code:

declare
  p_owner         varchar2(30);
  p_table_name    varchar2(30);

  TYPE OUTPUT_TAB_TYPE IS TABLE OF VARCHAR2(32767) index by binary_integer;
  OUTPUT_TAB OUTPUT_TAB_TYPE;

  l_columns_tab   dbms_sql.desc_tab;
  l_columns_cur   integer;
  l_columns_sql   varchar2(32767);
  l_columns_cnt   number;

  l_minmax_sql    varchar2(32767);
  l_minmax_cur    integer;
  l_minmax_tab    dbms_sql.desc_tab;
  l_minmax_cnt    number;

  l_fetch_ok      number;
  l_fetch_value   number;
begin

  p_owner := 'AMUSCH';
  p_table_name := 'GP';

  output_tab(1) := lpad(' ', 20, ' ');
  output_tab(2) := lpad('MIN_LENGTH', 20, ' ');
  output_tab(3) := lpad('MAX_LENGTH', 20, ' ');

  l_columns_sql := 'select * from ' || p_owner || '.' || p_table_name || 
     ' where 1 = 0';
  l_columns_cur := dbms_sql.open_cursor;
  dbms_sql.parse (l_columns_cur, l_columns_sql, dbms_sql.native);
  dbms_sql.describe_columns (l_columns_cur, l_columns_cnt, l_columns_tab);

  -- build the min/max sql statement
  l_minmax_sql := 'select ' ;
  for i in 1..l_columns_cnt
  loop
    l_minmax_sql := l_minmax_sql || 
          ' min(length(' || l_columns_tab(i).col_name || ')), ';
    l_minmax_sql := l_minmax_sql || 
          ' max(length(' || l_columns_tab(i).col_name || ')), ';
  end loop;
  l_minmax_sql := substr(l_minmax_sql, 1, 
                         length(l_minmax_sql) - 2); -- trim trailing comma
  l_minmax_sql := l_minmax_sql || ' from ' || p_owner || '.' || p_table_name;

  l_minmax_cur := dbms_sql.open_cursor;
  dbms_sql.parse (l_minmax_cur, l_minmax_sql, dbms_sql.native);
  dbms_sql.describe_columns (l_minmax_cur, l_minmax_cnt, l_minmax_tab);

  for i in 1..l_minmax_cnt
  loop
    dbms_sql.define_column(l_minmax_cur, i, l_fetch_value);
  end loop;

  l_fetch_ok := dbms_sql.execute(l_minmax_cur);

  loop
    l_fetch_ok := dbms_sql.fetch_rows(l_minmax_cur);
    exit when l_fetch_ok = 0;

    -- loop over the columns selected over
    for i in 1..l_columns_cnt
    loop
      output_tab(1) := output_tab(1) || '|' || l_columns_tab(i).col_name;

      dbms_sql.column_value(l_minmax_cur, (2*i-1), l_fetch_value);
      output_tab(2) := output_tab(2) || '|' || 
        lpad(l_fetch_value, length(l_columns_tab(i).col_name), ' ');
      dbms_sql.column_value(l_minmax_cur, (2*i), l_fetch_value);
      output_tab(3) := output_tab(3) || '|' || 
        lpad(l_fetch_value, length(l_columns_tab(i).col_name), ' ');

    end loop;
  end loop;

  if dbms_sql.is_open(l_minmax_cur) then
    dbms_sql.close_cursor (l_minmax_cur);
  end if;

  if dbms_sql.is_open (l_columns_cur) then
    dbms_sql.close_cursor (l_columns_cur);
  end if;

  for i in output_tab.first..output_tab.last
  loop
    dbms_output.put_line(output_tab(i));
  end loop;
end;
/

Results:

                |GP_ID|GGP_ID|OBJECT_NAME
      MIN_LENGTH|    1|     1|          9
      MAX_LENGTH|    7|     4|         41
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pl/sql - 集合可以循环遍历列名吗? 的相关文章

  • 我想从 Crystal Report .rpt 文件中提取 SQL 查询,有办法做到这一点吗?

    我想从 Crystal Report rpt 文件中提取 SQL 查询 有办法做到这一点吗 我没有任何 Crystal Reports 产品 只有 rpt 文件 下面是一个 Net 代码示例 它从给定目录中的所有 Crystal Repor
  • 如何使用 Alter Table 在 Access 中创建小数字段?

    我想以编程方式在 MS Access 表中创建一个新列 我尝试过很多排列ALTER TABLE MyTable Add MyField DECIMAL 9 4 NULL 并得到 字段定义中的语法错误 我可以轻松创建一个数字字段Double类
  • Wordnet sqlite 同义词和示例

    我正在尝试获取给定 wordid 的同义词和示例列表 经过大量的试验和错误 我可以获得所有同义词集的样本 但不是实际的同义词 这是我的查询 它给出了以下结果 select senses wordid senses synsetid sens
  • 如何从连接字符串中提取数据库名称,而不考虑 RDBMS?

    我正在研究一个不知道正在使用的 RDBMS 的课程 当然 应用程序的其余部分都清楚这一点 连接字符串是此类的输入 我需要数据库名称 无论 RDBMS 如何 如何从连接字符串中提取数据库名称 我读到以下问题 如何使用 SqlConnectio
  • xQuery LIKE 运算符?

    有没有办法以与 SQL 相同的方式使用 XQuery 执行 LIKE 操作 我不想构造一些 startswith endswith 和 contains 表达式 我想要实现的目标的示例 for x in user where x first
  • 如何从实体框架中的 .edmx 文件生成数据库?

    我不得不突然转而使用 Code First Entity Framework 4 1 一开始我对这个框架一无所知 但在过去的 8 个小时里 我现在对阅读博客和文章感到更加自在 特别是这个博客 http blogs msdn com b ad
  • 无法从 Web 主机本身以外的任何地方连接到任何 Web 主机的 MySQL 数据库

    我有 2 个不同的虚拟主机 pagodabox 000webhost 都是免费的 并且我已经设置了localhost与MySQL 我已经在他们三个上安装了 wordpress 它们在自己的域中工作得很好 即 什么时候localhostwor
  • 如何在oracle中获取表作为输出参数

    我正在尝试将 Oracle 过程调用的 out 参数强制转换为对象 它不起作用 因为 据我了解 我需要定义一个映射 它告诉方法如何转换它 如果地图为空或未正确填充 则它默认为 STRUCT 类型的对象 在我的情况下这是错误的 我已经构建了一
  • 删除前导零

    给定列中的数据 如下所示 00001 00 00026 00 我需要使用 SQL 删除空格后面的所有内容以及值中的所有前导零 以便最终输出为 1 26 我怎样才能最好地做到这一点 顺便说一句 我正在使用 DB2 这已在 DB2 for Li
  • C# 查询两个数据库的数据

    我目前有一个查询 我正在从两个不同的数据库获取数据 这些数据被附加到一个名为 accountbuys 的列表中 我的第一个表有三个数据条目 3个想要购买股票的帐户 下一张表有 17 个数据点 购买 17 只股票 I am merging t
  • oracle to_date 转换显示文字与字符串格式不匹配

    如果我使用 unixtime 转换器 我会得到 2005 年 5 月 31 日星期二 16 23 17 GMT 1117556597 如果我运行以下查询 则会收到错误 文字与字符串格式不匹配 这是为什么 select to date 111
  • VIEW for 表结合 UNION ALL 的 MySQL 性能

    假设我有 2 张桌子MySQL create table persons id bigint unsigned not null auto increment first name varchar 64 surname varchar 64
  • SQL Like 带有子查询

    我怎样才能做到这一点 SELECT FROM item WHERE item name LIKE SELECT equipment type FROM equipment type GROUP BY equipment type 内部子查询
  • 与常规 SQL 查询不同,为什么“linq to sql”查询以 FROM 关键字开头?

    为什么 linq to sql 查询以FROM与常规 SQL 查询不同的关键字 LINQ 模仿Logical Query processing在 SQL 中你有 8 SELECT 9 DISTINCT 11 TOP 1 FROM 2 ON
  • 过滤项目来源

    通过此代码 我设置了数据网格的 ItemsSource 不过 我有更多的 wpf 控件来过滤数据网格 例如从时间范围过滤数据网格 我可以为此编写一个新查询 但这似乎没有必要 因为数据已经可用 我只需要过滤它 最好的方法是什么 我能得到的任何
  • SQL 查询结果为字符串(或变量)

    是否可以将SQL查询结果输出到一个字符串或变量中 我的php和mysql不好 假设我有数据库 agents 其中包含列 agent id agent fname agent lname agent dept 使用此查询 sql SELECT
  • 关于 Cassandra 与 MySQL 的一些建议

    几天前我在这里问了一个问题 得到了一些非常好的答案 我正在考虑做一个带有个人资料 个人简介等的facebook风格的网站 并询问我是否应该使用mysql 答案是使用Cassandra 因为好多了 我只是问这是每个人都会建议的 只是我对mys
  • 创建和删除表空间 Oracle

    我已经创建了这个表空间 CREATE TABLESPACE IA643 TBS DATAFILE IA643 dat SIZE 500K AUTOEXTEND ON NEXT 300K MAXSIZE 100M 我尝试使用此命令删除它 DR
  • 如何将此本机 SQL 查询转换为 HQL

    所以我有这个很长的复杂的 Native SQLQuery string hql SELECT FROM SELECT a rownum r FROM select f2 filmid f2 realisateurid f2 titre f2
  • 调整 Oracle 数据库以加快启动速度(闪回)

    我正在使用 Oracle 数据库 11 2 我有一个场景 我发出FLASHBACK DATABASE经常 似乎有一个FLASHBACK DATABASECycle 会重新启动数据库实例 大约需要 1 分钟 我的设置花了 7 秒 数据库很小

随机推荐

  • 避免 Dart 中类的继承

    Dart 有没有办法避免继承 我正在寻找类似的东西 final class MyJavaClass 不直接 不 您可以编写一个带有私有构造函数的类并通过静态方法访问它们 class MyFinalClass MyFinalClass cto
  • 攻击者能否破解 iOS 钥匙串和数据保护加密? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在开发一个 iOS 应用程序 它
  • Linux中进程的空闲时间

    我需要计算Linux中进程的CPU使用率 用户模式 系统模式 空闲时间 我可以使用以下方法计算用户和系统模式下的使用情况utime and stime值来自 proc PID stat 但我没有发现任何与空闲时间相关的内容 我知道我可以从中
  • .Net 5 后台服务的 MSI 安装程序

    我有一个 Net 5 控制台应用程序 我试图将其作为 Windows 服务运行 我已阅读有关如何执行此操作的所有在线文章并成功完成 即 使用BackgroundService 问题是 我想要一个 MSI 安装程序来部署它 并且我读过的有关在
  • 在 Visual Basic 中打印(多)维数组

    有没有一种简单的方法可以将可能是多维的数组打印到 VB NET 中的控制台以进行调试 即仅检查数组的内容是否正确 来自 Objective C 背景NSLog函数打印格式相当良好的输出 例如一维数组的以下内容 myArray 0 gt He
  • 了解 applicationSignificantTimeChange:

    我发现有时我的应用程序 Cocos2d 游戏 在显着的时间变化后会出现 错误 例如 case 1 当应用程序进入后台并在几分钟后重新启动它时 我可以看到加载图像然后应用程序 游戏恢复 case 2 当应用程序进入后台并在很长一段时间后更改应
  • __NSAutoreleaseNoPool():类 General 自动释放的对象 0x753c2f0,没有适当的池 - 只是泄漏

    我已经有一段时间没有注意到我的控制台输出了 我突然注意到很多奇怪的错误 NSAutoreleaseNoPool Object 0x753c2f0 of class General autoreleased with no pool in p
  • 向行值添加尾随零以确保有 10 位数字

    如果我有一个数据帧 其中每行中的最大数字为 10 但由于尾随零已被截断 某些 ID 小于 10 那么如何在 python 中添加尾随零以确保每行中有 10 位数字 ID 1234567689 123456768 12345676 ID 12
  • Magento:使用分组子句过滤集合

    我想用分组子句过滤集合 在 SQL 中 这看起来像 SELECT FROM my table WHERE col1 x AND col2 y OR col3 z 我如何将其 翻译 为过滤集合 gt addFieldToFilter Than
  • Jenkins 无法使用 SVN 凭据或下载新插件/新版本

    谁能建议如何解决这两个问题 无法升级Jenkins和SVN插件 无法连接到svn 我正在 Windows 64 位机器上设置 Jenkins 它被配置为作为 Windows 服务运行 我们在 Windows 7 64 位操作系统上运行它 詹
  • 如何在Springboot Restcontroller中使用PUT方法?

    正在使用 Spring boot 开发一个应用程序 我尝试了所有表示动词 如 GET POST DELETE 它们也都工作正常 使用 PUT 方法 Spring Boot 不支持 我是否需要添加任何新配置 Put方法仅适用于没有任何参数的请
  • 模型中包含的辅助方法会产生“未定义的局部变量或方法‘config’”错误

    我有一个非常复杂的辅助方法 也需要在模型中 我已经通过在模型中包含一些助手来完成此操作 但相同的方法不适用于 Rails 3 0 7 module ContentsHelper def content teaser record it us
  • 为什么转换为单击一次应用程序或exe后不进行日志记录?

    我创建了一个控制台应用程序 其中使用 log4net 正确完成日志记录 但是在发布我的应用程序 单击一次应用程序或 exe 后 即使我的应用程序工作正常 日志记录也无法正常工作 有什么方法可以让 log4net 在我的最终点击应用程序中工作
  • Linux邮件添加内容类型标头不起作用

    我在用mail从我的 Linux 系统发送邮件的命令 我遇到的问题是邮件的内容类型始终为Content Type text plain charset us ascii 我正在发送 html 内容 它显示为纯文本 这就是我尝试过的 1 bo
  • 纯文本文档的字符编码未声明 - mootool 脚本

    我刚刚注意到有一个warning当我在 FireFox 浏览器上查看 mootool js 脚本时 会弹出消息 警告消息是 纯文本文档的字符编码未声明 文档在某些浏览器中会呈现乱码 如果文档包含来自外部的字符 则配置 US ASCII 范围
  • 在 Sonata 管理列表中使用自定义列

    我使用 Symfony 4 1 创建了一个项目 并安装了 Sonata Admin Bundle 在我的类别列表中 我尝试添加与类别字段不相关的列 所以我做了 Admin CategoryAdmin php protected functi
  • 类成员和显式堆栈/堆分配

    假设我们有 4 个类 如下所示 class A public A void m B private B m B class B public B void m i 1 private int m i class C public C voi
  • TextView文本缩小到给定宽度

    我的活动中有一个文本视图字段 其字体大小为 16 其文本是通过代码设置的 假设如果我有一个大文本 它应该缩小该数据 即字体大小减小 而不是转到下一行 我该怎么做
  • Visual Basic 中的屏幕尺寸

    如何在 Visual Basic 中访问屏幕尺寸 我在网上查看过 它说要使用 Screen width 和 Screen length 但它无法识别这些属性 有什么提示吗 在VB中你可以使用Screen Width and Screen H
  • pl/sql - 集合可以循环遍历列名吗?

    以下代码的输出是 LAT MISC SID NO MIN LENGTH 1 2 1 1 MAX LENGTH 6 6 4 2 输出正如我所期望的那样 但是无论如何都可以使用索引 即j 循环遍历列而不是执行RESULTS I 最长长度 结果