如何映射位于单独表中的列名?

时间:2021-06-02 21:20:56

标签: sql oracle

我有一个带有列名和标识符的表 COLUMNS:

Open

还有一个表 DATA,其列名为 ID 而不是 COL_NAME:

ID | COL_NAME <- column headers
1  | 'col1'
2  | 'col2'
3  | 'col3'

如何在查询中将 COL_NAME 中的值映射到 DATA 中的列名?我不想更改实际表格。

例如 1 | 2 | 3 <- column headers x | y | z a | b | c

最终输出应该是:

select * from DATA [...]

1 个答案:

答案 0 :(得分:0)

大多数情况下,你没有。

如果您使用第 3 方应用程序(即 Java、C++、C#、Python 等)以编程方式访问数据库,那么您应该使用两个单独的查询在该第 3 方应用程序中执行此转换:

SELECT id, col_name FROM columns;

然后

SELECT * FROM data;

然后当您显示第二个查询的输出时,您可以替换列标题。


您还可以使用字符串连接来替换列名来构建第二个查询;但是,您需要确保不会在您的应用程序中引入 SQL 注入漏洞。

例如,第三方应用的伪代码:

results1 = query( "SELECT id, col_name FROM columns" );
sql = "SELECT ";
i = 0;

for ( row in results1 )
{
  if ( i > 0 )
  {
    sql += ", ";
  }
  sql += `"{sql_escape(row.id)}" AS "{sql_escape(row.col_name)}"`;
  i++;
}
sql += " FROM data";

results2 = query( sql );
// output the results.

如果你想完全在 Oracle 中完成,那么你不能只使用 SQL 来完成;您需要使用 PL/SQL 来生成动态 SQL 语句。例如:

DECLARE
  v_sql VARCHAR2(4000);
BEGIN
  v_sql := 'SELECT ';
  FOR row IN ( SELECT * FROM columns ORDER BY id ) LOOP
    v_sql := v_sql || DBMS_ASSERT.ENQUOTE_NAME( row.id )
                   || ' AS '
                   || DBMS_ASSERT.ENQUOTE_NAME( row.col_name )
                   || ', ';
  END LOOP;
  v_sql := RTRIM( v_sql, ', ' ) || ' FROM data';
  DBMS_OUTPUT.PUT_LINE( v_sql );
END;
/

哪个将输出查询:

<块引用>
SELECT "1" AS "COL1", "2" AS "COL2", "3" AS "COL3" FROM data

db<>fiddle here

您可以复制粘贴并执行它(或在游标中使用它并遍历游标)。