我试图打印多个表格行,而我们不知道列名称。我从一天开始尝试这个,我想出了这个错误的过程,并且必须声明emp_dummy_col'。请帮帮我。 谢谢。
create or replace procedure sp_display
as
CURSOR cur_emp is select EMP_ID,EMP_NAME,DEPT_IT,DOJ,LOCATION from employee;
emp_rows cur_emp%rowtype;
type emp_table is table of emp_rows%type;
emp_dummy_table emp_table;
CURSOR cur_col is select column_name from user_tab_cols where table_name ='EMPLOYEE';
emp_row cur_col%rowtype;
type emp_table1 is table of emp_row%type;
emp_dummy_col emp_table1;
begin
open cur_emp;
fetch cur_emp bulk collect into emp_dummy_table;
close cur_emp;
open cur_col;
fetch cur_col bulk COLLECT into emp_dummy_col;
close cur_col;
for i in 1..emp_dummy_table.count
loop
for j in 1..emp_dummy_col.count
loop
DBMS_OUTPUT.PUT_LINE(emp_dummy_table(i).emp_dummy_col(j));
end loop;
end loop;
end;
答案 0 :(得分:1)
如Justin Cave所述,您可以使用包DBMS_SQL
进行大量工作。
以下只是一个简单的例子。
SET SERVEROUTPUT ON
SET FEEDBACK OFF
CLEAR
DECLARE
-- The SQL Statement
V_SQL VARCHAR2(4000) := 'select EMP_ID,EMP_NAME,DEPT_IT,DOJ,LOCATION from employee';
-- The cursor (number) variable
V_CURSOR INTEGER;
-- Variable to hold the return value of DBMS_SQL.EXECUTE (Number of processed rows)
V_NUM_ROWS NUMBER;
-- Variable to hold the return value of DBMS_SQL.DESCRIBE_COLUMNS
V_COL_CNT INTEGER;
-- Column description table. Outcome from DBMS_SQL.DESCRIBE_COLUMNS
V_DESC DBMS_SQL.DESC_TAB;
-- Variable for the current column number when iterating over the column description collection
V_COL_NUM NUMBER;
-- (generic) Variable for a VARCHAR2-Column
V_VARC_COL VARCHAR2(4000);
-- (generic) Variable for a NUMBER-Column
V_NUM_COL NUMBER;
BEGIN
-- Open a cursor
V_CURSOR := DBMS_SQL.OPEN_CURSOR;
-- Parse the SQL-Query (without any bindings etc.)
DBMS_SQL.PARSE(V_CURSOR, V_SQL, DBMS_SQL.NATIVE);
-- Execute the parsed query and return the number of processed rows.
-- May be 0 or undefined on SELECT- and DDL-Statements and should be ignored
V_NUM_ROWS := DBMS_SQL.EXECUTE(V_CURSOR);
-- Get the columns description table
DBMS_SQL.DESCRIBE_COLUMNS(V_CURSOR, V_COL_CNT, V_DESC);
V_COL_NUM := V_DESC.FIRST;
IF (V_COL_NUM IS NOT NULL) THEN
LOOP
-- Assign variables to column types
CASE V_DESC(V_COL_NUM).COL_TYPE
WHEN DBMS_SQL.NUMBER_TYPE THEN
DBMS_SQL.DEFINE_COLUMN(V_CURSOR, V_COL_NUM, V_NUM_COL);
WHEN DBMS_SQL.VARCHAR2_TYPE THEN
DBMS_SQL.DEFINE_COLUMN(V_CURSOR, V_COL_NUM, V_VARC_COL, 4000);
-- more branches if other column types are expected/supported (Date, LOBs etc.)
ELSE
NULL;
END CASE;
V_COL_NUM := V_DESC.NEXT(V_COL_NUM);
EXIT WHEN(V_COL_NUM IS NULL);
END LOOP;
-- Fetch the rows
V_NUM_ROWS := DBMS_SQL.FETCH_ROWS(V_CURSOR);
IF (V_NUM_ROWS > 0) THEN
LOOP
-- Column handling
FOR L_I IN V_DESC.FIRST .. V_DESC.LAST LOOP
CASE V_DESC(L_I).COL_TYPE
-- NUMBER column type value handler
WHEN DBMS_SQL.NUMBER_TYPE THEN
DBMS_SQL.COLUMN_VALUE(V_CURSOR, L_I, V_NUM_COL);
V_VARC_COL := TO_CHAR(V_NUM_COL);
-- VARCHAR2 column type value handler
WHEN DBMS_SQL.VARCHAR2_TYPE THEN
DBMS_SQL.COLUMN_VALUE(V_CURSOR, L_I, V_VARC_COL);
-- more branches if other column types are expected/supported (Date, LOBs etc.)
ELSE
--Handling for unsupported column types (if necessary)
NULL;
END CASE;
DBMS_OUTPUT.PUT(V_DESC(L_I).COL_NAME || '" = "' || V_VARC_COL || '"');
IF (L_I < V_DESC.COUNT) THEN
DBMS_OUTPUT.PUT(' | ');
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
-- Fetch the next row
V_NUM_ROWS := DBMS_SQL.FETCH_ROWS(V_CURSOR);
-- Exit loop if no more row is fetched
EXIT WHEN V_NUM_ROWS = 0;
END LOOP;
END IF;
END IF;
-- Close the cursor (important!)
DBMS_SQL.CLOSE_CURSOR(V_CURSOR);
EXCEPTION
WHEN OTHERS THEN
-- Close the cursor (important!) if any error occurs
IF (DBMS_SQL.IS_OPEN(V_CURSOR)) THEN
DBMS_SQL.CLOSE_CURSOR(V_CURSOR);
END IF;
-- Rethrow the exception
RAISE;
END;
/
有关DBMS_SQL的详细/进一步信息:
!!安全警告!!
使用这种动态SQL容易受到SQL注入和其他技术的攻击!
答案 1 :(得分:1)
嗯,你所拥有的代码示例并没有真正满足你的要求。它希望您告诉列,请参阅:
从员工中选择EMP_ID,EMP_NAME,DEPT_IT,DOJ,LOCATION;
1)你可以得到像这样的表的未知列(我在这个例子中使用表NEWS)
begin
for rec in
(select column_name from user_tab_cols
where table_name='NEWS') loop
dbms_output.put_line(rec.column_name);
end loop;
end;
2)如果你想要打印出数据,那就是非常讨厌PLSQL,请参阅Cursor For Loop with dynamic SQL-Statement
3)如果您对某些妥协做得很好,请尝试这种方法。我从user_tab_cols中学习的字段构建了一个动态SQL语句。动态SQL将每列的字符串值连接成一行,最后我在此处获取一个游标。
为方便起见,我还在标题变量中收集列名。
declare
statement varchar2(4000);
header varchar2(4000);
TYPE TCur IS REF CURSOR;
cur TCur;
TYPE TRec IS RECORD (
line varchar2(4000)
);
rec TRec;
begin
for rec in
(select column_name from user_tab_cols
where table_name='NEWS') loop
if statement is not null then
statement:=statement||'||'',''||';
header:=header||',';
end if;
statement:=statement||rec.column_name;
header:=header||rec.column_name;
end loop;
statement:='select '||statement||' as line from '||'NEWS';
dbms_output.put_line(header);
open cur for statement;
loop
fetch cur into rec;
exit when cur%notfound;
dbms_output.put_line(rec.line);
end loop;
close cur;
end;
给予:
NEWS_ID,NEWS
0,Some new PLSQL hack has been done
1,And the day is not over yet!