在以下查询中,select_string可以返回包含任何可能数据类型的任意数量的列和行。
Execute immediate 'select_string' into v_table_variable;
例如,select_string可以是'select name, last name from student'
或'select date, subject, address , phone from booking'
,依此类推。
有没有人知道我如何定义v_table_variable以便按需要运行execute immediate ?!我打算之后做一个循环来读取这个变量的值。
非常感谢!
答案 0 :(得分:2)
"全面爆发" dynmamic版本将是这个(未经测试):
DECLARE
v_stmt_str VARCHAR2(200);
v_cur INTEGER;
v_rows_processed INTEGER;
col_cnt INTEGER;
rec_tab DBMS_SQL.DESC_TAB;
rec DBMS_SQL.DESC_REC;
num_var NUMBER;
string_var VARCHAR2(4000);
date_var DATE;
-- .. some more variables if needed
BEGIN
v_cur := DBMS_SQL.OPEN_CURSOR; -- open cursor
v_stmt_str := 'SELECT whatever from ....';
DBMS_SQL.PARSE(v_cur, v_stmt_str, DBMS_SQL.NATIVE);
DBMS_SQL.DESCRIBE_COLUMNS(v_cur, col_cnt, rec_tab);
FOR c in 1..col_cnt LOOP
rec := rec_tab(c);
IF rec.col_type = DBMS_TYPES.TYPECODE_NUMBER THEN
DBMS_SQL.DEFINE_COLUMN(v_cur, c, num_var);
ELSIF rec.col_type = DBMS_TYPES.TYPECODE_VARCHAR2 THEN
DBMS_SQL.DEFINE_COLUMN(v_cur, c, string_var, rec.col_max_len);
ELSIF rec.col_type = DBMS_TYPES.TYPECODE_DATE THEN
DBMS_SQL.DEFINE_COLUMN(v_cur, c, date_var);
-- .. some more data types if needed
END IF;
END LOOP;
-- Execute
v_rows_processed := DBMS_SQL.EXECUTE(v_cur);
LOOP
-- Fetch a row
IF DBMS_SQL.FETCH_ROWS(v_cur) > 0 THEN
FOR c in 1..col_cnt LOOP
rec := rec_tab(c);
IF rec.col_type = DBMS_TYPES.TYPECODE_NUMBER THEN
DBMS_SQL.COLUMN_VALUE(v_cur, c, num_var);
ELSIF rec.col_type = DBMS_TYPES.TYPECODE_VARCHAR2 THEN
DBMS_SQL.COLUMN_VALUE(v_cur, c, string_var);
ELSIF rec.col_type = DBMS_TYPES.TYPECODE_DATE THEN
DBMS_SQL.COLUMN_VALUE(v_cur, c, date_var);
-- .. some more data types if needed
END IF;
END LOOP;
-- Process: do something with num_var or string_var or date_var values
ELSE
EXIT;
END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(v_cur); -- close cursor
END;
/
但正如评论中已经说明的那样,如果你真的需要它,请检查你的要求,这可能不是。
检查Oracle文档Coding Dynamic SQL和DBMS_SQL以获取其他示例。有各种方法提供不同的水平"动态的。