程序主体内的光标
Posted
技术标签:
【中文标题】程序主体内的光标【英文标题】:Cursor inside procedure body 【发布时间】:2015-10-27 10:48:52 【问题描述】:我试图在过程体中声明一个游标。 我知道它应该在声明块中完成,但是游标引用的表是在过程主体内创建的。
--TABLE MAY OR MAY NOT BE PRESENT PRIOR TO PROCEDURE EXECUTION
SELECT COUNT(*)
INTO ln_cnt
FROM User_Tables
WHERE table_name = 'TMP$UOM_COMBO_GEN';
IF ln_cnt > 0 THEN
EXECUTE IMMEDIATE ' CREATE TABLE TMP$UOM_COMBO_GEN (UOM_ID VARCHAR2(20 BYTE), HIER_CODE VARCHAR2(20 BYTE),NODE_CODE VARCHAR2(200 BYTE))';
END IF;
CURSOR C_HIER
IS
SELECT DISTINCT HIER_CODE FROM TMP$UOM_COMBO_GEN WHERE UOM_ID=P_UOM_ID;
FOR HIER IN C_HIER
LOOP
IF C_HIER%ROWCOUNT = 1 THEN
LV_SQL2 := '(SELECT UOM_ID, NODE_CODE '||HIER.HIER_CODE||' FROM TMP$UOM_COMBO_GEN WHERE UOM_ID='''||P_UOM_ID||''' AND HIER_CODE='''||HIER.HIER_CODE||''')'||HIER.HIER_CODE;
LV_SORT := ' ORDER BY '||HIER.HIER_CODE||'';
LV_SQL := 'SELECT * FROM ' || LV_SQL2;
ELSE
LV_SQL3 := ' LEFT OUTER JOIN(SELECT NODE_CODE '||HIER.HIER_CODE||' FROM TMP$UOM_COMBO_GEN WHERE UOM_ID='''||P_UOM_ID||''' AND HIER_CODE='''||HIER.HIER_CODE||''')'||HIER.HIER_CODE ||' ON 1=1';
LV_SORT := LV_SORT||','||HIER.HIER_CODE||'';
LV_SQL := LV_SQL || LV_SQL3;
END IF;
END LOOP;
我收到以下错误。
错误(17,10):PLS-00103:在预期以下之一时遇到符号“C_HIER”::=。 (@%;
【问题讨论】:
如果动态创建表,总是要使用动态SQL来引用它。不能使用静态 SQL 打开游标。你为什么首先使用动态 SQL 来创建表?在运行时创建对象通常是一种非常糟糕的方法,所以我最初的偏见是摆脱这种方法。如果TMP$
表示一个临时表,而您实际上需要一个表对象而不是集合,则创建一次全局临时表并像使用任何其他表一样使用它。
【参考方案1】:
一个表一旦创建就存储在数据库中,你可以从你想在模式中引用的任何地方引用它。
您的代码可能需要在以下部分进行更改
SELECT COUNT(*)
INTO ln_cnt
FROM User_Tables
WHERE table_name = 'TMP$UOM_COMBO_GEN';
IF ln_cnt > 0 THEN -- means only if table exists u want to create the table which will
--throw an exception if table is already there ,
--so better equate it to 0
EXECUTE IMMEDIATE ' CREATE TABLE TMP$UOM_COMBO_GEN (UOM_ID VARCHAR2(20 BYTE), HIER_CODE VARCHAR2(20 BYTE),NODE_CODE VARCHAR2(200 BYTE))';
END IF;
现在,如果您确实需要在每次某些条件为真/假时创建一个新表,并且您想在游标中选择表,请使用参考游标执行以下操作
create or replace procedure abc(Table_name varchar2 , param_list varchar2 , where_clause varchar2) is
c_hier sys_refcursor ;
LV_SQL2 varchar2(2000) ;
LV_SORT varchar2(2000) ;
LV_SQL varchar2(2000) ;
LV_SQL3 varchar2(2000) ;
begin
SELECT COUNT(*)
INTO ln_cnt
FROM User_Tables
WHERE table_name = Table_name; -- Use any table here
IF ln_cnt = 0 THEN
EXECUTE IMMEDIATE ' CREATE TABLE '||Table_name||' '||param_list;
END IF;
open c_hier for 'SELECT DISTINCT '||param_list||' FROM '||table_name||' '||where_clause;
FOR HIER IN C_HIER
LOOP
IF C_HIER%ROWCOUNT = 1 THEN
LV_SQL2 := '(SELECT UOM_ID, NODE_CODE '||HIER.HIER_CODE||' FROM TMP$UOM_COMBO_GEN WHERE UOM_ID='''||P_UOM_ID||''' AND HIER_CODE='''||HIER.HIER_CODE||''')'||HIER.HIER_CODE;
LV_SORT := ' ORDER BY '||HIER.HIER_CODE||'';
LV_SQL := 'SELECT * FROM ' || LV_SQL2;
ELSE
LV_SQL3 := ' LEFT OUTER JOIN(SELECT NODE_CODE '||HIER.HIER_CODE||' FROM TMP$UOM_COMBO_GEN WHERE UOM_ID='''||P_UOM_ID||''' AND HIER_CODE='''||HIER.HIER_CODE||''')'||HIER.HIER_CODE ||' ON 1=1';
LV_SORT := LV_SORT||','||HIER.HIER_CODE||'';
LV_SQL := LV_SQL || LV_SQL3;
END IF;
END LOOP;
【讨论】:
以上是关于程序主体内的光标的主要内容,如果未能解决你的问题,请参考以下文章
ios11,弹出层内的input框光标错位 键盘弹出时,输入信息,光标一直乱跳