我的目标是保留一个包含绑定值和参数的表,稍后将由dbms_sql使用。下面的pl / sql示例是基本的,它的目的是说明我从调用先前循环对象的值时遇到的问题。
表 account_table 包含帐户信息
CREATE TABLE account_table (account number, name varchar2(100)));
INSERT INTO mytest
(account, name)
VALUES
(1 ,'Test');
COMMIT;
表 MYTEST 包含绑定信息
CREATE TABLE mytest (bind_value varchar2(100));
INSERT INTO mytest (bind_value) VALUES ('i.account');
COMMIT;
DECLARE
v_sql VARCHAR2(4000) := NULL;
v_ret VARCHAR2(4000) := NULL;
BEGIN
FOR I IN (
SELECT account
FROM account_table
WHERE ROWNUM = 1
) LOOP
FOR REC IN (
SELECT *
FROM mytest
) LOOP
v_sql := 'SELECT ' || rec.bind_value || ' FROM dual';
EXECUTE IMMEDIATE v_sql INTO v_ret;
dbms_output.put_line ('Account: ' || v_ret);
END LOOP;
END LOOP;
END;
/
我无法存储名称 i.account ,稍后会使用该对象的值。我的想法是使用NDS;但是,虽然 v_sql 的值看起来没问题(它将显示为“从双重选择i.account”),但 i.account 会引发无效标识符的例外情况。有没有办法获得对象的价值?我们使用的是Oracle 11g2。 谢谢!
答案 0 :(得分:1)
动态SQL不具有PL / SQL块的上下文。您不能在动态SQL语句中使用PL / SQL块中定义的标识符。因此,您无法引用i.account
并引用您在动态SQL语句之外定义的循环。当然,您可以动态生成整个PL / SQL块,但动态PL / SQL通常是一种非常糟糕的方法 - 很难做到这一点。
但是,如果您尝试使用i.account
的值,则可以执行类似
v_sql := 'SELECT :1 FROM dual';
EXECUTE IMMEDIATE v_sql
INTO v_ret
USING i.account;
但是,如果您想从表格中获取字符串i.account
,那似乎无法帮助您。
答案 1 :(得分:1)
您是否总是尝试使用相同的where子句访问同一个表,但每次只查找不同的列?如果是这样,你可以这样做:
p_what_I_want := 'ACCOUNT';
--
SELECT decode(p_what_I_want
,'ACCOUNT', i.account
, 'OTHER_THING_1', i.other_thing_1
, 'OTHER_THING_2', i.other_thing_2
, 'OTHER_THING_1', i.default_thing) out_thing
INTO l_thing
FROM table;
上述声明不是动态的,但会根据需要返回不同的列...