不确定这是否可行,但我试图尽可能少地进行手工操作。
根据不同的因素组合,我有一个包含150列的表格。 我希望提取列名称,其中某个特定字符串在列名称中。
我做了以下这样做。这是我所拥有的基本例子
--Create the table
Create Table temp
(id number,
Fac1_Fac2_Fac_3_Fac4_Fac5 number,
Fac1_Fac6_Fac_3_Fac4_Fac5 number,
Fac1_Fac6_Fac_7_Fac4_Fac5 number,
Fac1_Fac9_Fac_3_Fac4_Fac5 number,
Fac1_Fac10_Fac_3_Fac4_Fac5 number,
Fac1_Fac2_Fac_3_Fac11_Fac5 number,
Fac1_Fac2_Fac_3_Fac4_Fac12 number,
Fac13_Fac2_Fac_3_Fac4_Fac5 number);
Insert into temp Values (1,35634,3243,343,564,56,4635,3,334);
Insert into temp Values (2,3434234,3243,343,564,56,435,3,34234);
Insert into temp Values (3,5555,3243,33,564,56,435,3,3434);
Insert into temp Values (4,34234,343,343,564,56,4335,3,34);
commit;
--Extract Column Names
Select * from (
Select COLUMN_NAME
from user_tab_cols
where lower(table_name) ='temp'
)
where column_name like '%FAC13%'
--This is what I want to automate.
Select id, FAC13_FAC2_FAC_3_FAC4_FAC5
From temp
--I want the column name to come fron the select statment above as there may be lots of names.
基本上,如果可能的话,我想在一个查询中选择表格中包含Fac13的所有行。
谢谢
答案 0 :(得分:2)
我认为你不能在一个查询中做到这一点。首先,您的extract column names query
可以简化为一个查询作为游标,然后使用动态选择语句,如下所示:
CREATE OR REPLACE proc_dyn_select IS
CURSOR c1 IS
SELECT column_name
FROM user_tab_cols
WHERE LOWER(table_name) ='temp' and column_name LIKE '%FAC13%';
cols c1%ROWTYPE;
sqlstmt VARCHAR2(2000);
BEGIN
OPEN c1;
LOOP
FETCH c1 into cols;
EXIT WHEN c1%NOTFOUND;
sqlstmt := sqlstmt ||cols.column_name||',';
END LOOP;
CLOSE c1;
sqlstmt := 'select '||substr(sqlstmt, 1, length(sqlstmt)-1)||' FROM temp';
EXECUTE IMMEDIATE sqlstmt;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('error '||sqlerrm);
END;
/
解释
首先,游标将存储符合条件的列(来自表temp
,列名称具有子字符串FAC13
。然后在执行部分({{1}之后) }),您将使用存储在游标BEGIN
中的列名来动态构建查询。对于每一轮循环,列名称将作为字符串添加并与逗号连接。因此,一列列将是像c1
这样构建。字符串存储在sqlstmt变量中。
循环结束后,通过添加关键字'col1, col2, col3, ... coln,'
,SELECT
和表名来修改字符串以构建sql语句。但是,我们删除了FROM
变量的最后一个字符,因为它是一个额外的逗号。
sqlstmt
语句将运行存储在EXECUTE IMMEDIATE
。
通过使用过程,您始终可以传递参数,以便此过程可以执行您想要的任何动态sql语句。