Sql 如何按ID或索引号引用列

Sql 如何按ID或索引号引用列,sql,oracle,Sql,Oracle,在OraclePL/SQL中,我运行了一个查询,并试图逐一读取每一行的每一列,以便能够将它们与分隔符硬格式要求连接在一起。该脚本用于多个大小不同的表,因此列数事先不知道。我曾经 SELECT COUNT(column_name) INTO NumColumns FROM all_tabs_cols WHERE table_name = Table_Array(i); 其中表_数组已经定义。这是在for循环的中间,并成功地获得了列的总数。表_游标是SELECT*语句。在这之后,我试着做一些类似的

在OraclePL/SQL中,我运行了一个查询,并试图逐一读取每一行的每一列,以便能够将它们与分隔符硬格式要求连接在一起。该脚本用于多个大小不同的表,因此列数事先不知道。我曾经

SELECT COUNT(column_name) INTO NumColumns FROM all_tabs_cols
WHERE table_name = Table_Array(i);
其中表_数组已经定义。这是在for循环的中间,并成功地获得了列的总数。表_游标是SELECT*语句。在这之后,我试着做一些类似的事情

FOR j IN 0..NumColumns-1 LOOP
    FETCH TABLE_CURSOR.column(j) INTO DataValue;
    DBMS_OUTPUT.PUT(DataValue || '/');
END LOOP

以上是伪代码。它说明了我所追求的概念。我对PL/SQL不太了解,不知道如何从一行中获取这样的值。我还担心在执行此操作时会意外地移动光标。如何完成此任务?

这是代码的外观:

SELECT F1 || ', ' || F2 || ', ' || ... || ', ' || FN
FROM TABLE
无回路

下面是如何生成不使用循环的代码。 注意,如果需要,可以取出where语句并为整个数据库生成代码。 首先只使用一个表进行测试

SELECT 'SELECT '|| LISTAGG(COLUMN_NAME, ' || '', '' || ') || ' FROM '||TABLE_NAME as sql_stm
FROM ALL_TAB_COLUMNS 
WHERE TABLE_NAME='tablename'
GROUP BY TABLE_NAME;

您必须使用某种形式的动态SQL。下面是一个简单的例子:

它构建SQL语句,该语句将从所需的表中选择“/”分隔列。然后它使用动态SQL来运行该SQL语句

DECLARE
  p_table_name VARCHAR2(30) := 'DBA_OBJECTS';
  l_sql VARCHAR2(32000);

  TYPE varchar2tab IS TABLE OF VARCHAR2(32000);
  l_array varchar2tab;

BEGIN
  SELECT 'SELECT ' || listagg(column_name,' ||''/''||') within group ( order by column_id ) || ' FROM ' || owner || '.' || table_name || ' WHERE ROWNUM <= 100'
  INTO l_sql
  FROM dba_tab_columns
  where table_Name = 'DBA_OBJECTS'
  group by owner, table_Name;

  EXECUTE IMMEDIATE l_sql BULK COLLECT INTO l_array;

  FOR i in l_array.first .. l_array.last LOOP
    dbms_output.put_line(l_array(i));
  END LOOP;
END;

谁不只是使用Listag或其他聚合函数?这不是使用SQL的方式-SQL是基于集合的-只要你一看,你就有麻烦了。@Hogan,我很害怕。那么,有什么更好的方法来获取这些信息呢?@OldProgrammer,LISTAGG会很棒,因为我已经用它来获取标题信息了。问题在于,它似乎只是沿着列向下,而不是横穿行。我有1000行和3列,我需要1/A1/B1/C1,然后是2/A2/B2/C2,等等。有没有一种方法可以使LISTAGG跨一行工作?@SandPiper-最好的方法是编写一些代码,生成快速的代码并运行这些代码。看我的答案——只有一行。所以你的意思是,如果他有1000张桌子,他每次都要用上面的方法。我希望你能理解我的意思,这没有什么帮助。我的问题和@Raj_Te说的一模一样。我有很多表格,表格结构偶尔会改变。我无法控制这一切。我必须使用动态SQL脚本来实现它。我不知道表的列名是什么,这就是为什么我需要通过索引来引用它。不要使用循环。循环很慢。小调:是Listag,不是LIST_AGG。这就像冠军一样。我唯一改变的是,在运行executeimmediate之前,我将整个l_sql组合成一个字符串。非常感谢你!不客气。确保添加了适当的错误处理。甲骨文行可以很多!超过32000字节。此外,这对具有特定数据类型(例如LONG)的表不起作用。我仍在学习SQL。出于好奇,为什么它不能处理长数据类型?其他的呢?LONG不能隐式转换为VARCHAR2。事实上,它甚至不能显式转换为VARCHAR2。他们只是一个痛苦的工作,我敢肯定,99%的人都会感到兴奋,如果甲骨文刚刚摆脱他们。其他类型?我不确定。。。无法隐式转换为VARCHAR2的任何内容。我的脑海里总是跳出长长的一段。也许一些专门的Oracle空间数据类型可能存在问题。所有常见的数据类型:NUMBER、DATE、VARCHAR2都可以。但是,请参见下一条注释…日期列将使用NLS_DATE_格式设置隐式转换。最好使用to_DATE_columnName、'DD-MON-YYYY'或类似的名称来构建SQL。