ORACLE 将表名作为变量
(记录一下我最近做的事情,从有想法到实验成功)
使用Oracle编写存储过程,操作一样 但是就是表名不一样 想把表名作为变量赋值 来做循环(实例)
经常使用的存储过程中,变量可以直接放在里面:(插入更新都是可以直接使用变量作为条件)
以下都是随机编写的简单例子,只是用来说明一下正确写法。
create or replace procedure cheshi
is
V_A varchar2(20);
begin
V_A:='12';
select * from CESHI where T1 = V_A ;
update CESHI set T1 = V_A ;
end;
但是当想用变量作为表名的话,就不能使用这样的写法 所以使用动态sql ,基本的动态sql使用拼连条件变量:(使用 " || " 拼连变量)
create or replace procedure cheshi
is
v_sql varchar2(2000);
V_A varchar2(20);
begin
V_A:='12';
v_sql := 'select * from CESHI where T1 ='|| V_A ;
execute immediate v_sql;
end;
所以使用表名作为变量:这样就成功可以将表名作为变量啦!!
create or replace procedure(s OUT sys_refcursor)
is
v_sql varchar2(2000);
v_t_name varchar2(100);
V_A varchar2(20);
begin
v_t_name:='CESHI';
v_sql := 'select * from' || v_t_name || ' WHERE T2='|| V_A ;
open s for v_sql;
end;
但是我的需求不仅要将变量作为表名,还想要将查询的结果赋给变量,刚开始想法是
能编译成功,但是执行的话会提示语句不正确,主要原因还是因为 sql里面是不能这样写的
正确的写法应该是:execute immediate v_sql into V_A;(执行结果赋给变量)
create or replace procedure cheshi(out_avg OUT varchar)
is
v_sql varchar2(2000);
v_t_name varchar2(100);
V_A varchar2(20);
begin
V_A:='12';
v_t_name:='CESHI';
v_sql := 'select count(1) from ' || v_t_name || ' where T1 ='|| V_A ;
execute immediate v_sql into V_A;
out_avg:=V_A;
dbms_output.put_line(out_avg);
end;
执行结果:
啊啊啊啊 在转到我正式的存储过程写的时候遇到了很多问题,全部都是编译成功,执行的时候提示
1、sql command not properly ended
2、keyword not found where expected
这两个问题都是sql语句不成确的问题 首先要检查sql语句 检查完发现该有的都有了 自己拿出来替换变量也能查询
最后发现问题是 没有空格 !!!吐血!!! 就是动态sql语句里面逗号和关键词之间必须要有距离!!!上面两个错误都是因为这个原因!!!(当然是你的语句本来就没有问题的前提下)
还有遇到一个错误、加入时间条件的时候: 正常的动态sql 不能像如下(下图错误写法示例 | )直接写入条件里面,因为逗号之间会影响
所以我本来想法是把DD定义成一个变量,使用变量传进去 如下(下图错误写法示例 | ),使用以上的传参方法
以上两个方法 这样子 编译成功 但是测试执行的时候就会提示错误 "DD" invalid identifier
可见 这样传参进去 是不正确的
所以我改成另一个传参方法(下面这个就是正确写法啦!!!)
可能正常条件可以直接使用变量 但是条件中使用函数的变量值还是用第二种传参方式吧...
附加存储过程的常见错误
plsql00428:select 里面缺少into子句。
出现这个问题是为什么呢 这是别人问我的 那我就这个例子来记录一下:
执行的时候 会提示第6行和第9行:plsql00428:select 里面缺少into子句。
原理是因为:
在pl/sql程序中不允许出现不带into子句的select语句。
相当于不带into 赋值结果给变量的select语句在存储过程中是没有用的
一般写存储过程都是根据赋值的变量判断大小 最后对数据进行增加删除修改这类操作 如果接的 是select 判断完之后就查看一下原表数据?? 想当然是没有用的
所以得改一下自己想要的存储过程的作用是什么 整个逻辑有没有问题