查看: 463|回复: 8

%rowtype动态指定表名

[复制链接]
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-11 17:17 | 显示全部楼层 |阅读模式
看了下面帖子,还是不明白怎么解决。
http://www.itpub.net/thread-1313303-1-1.html

是不是下面这样子就行了???
可越想越不对啊。我这传进来的表是动态的啊。也就是说tr里面的recode都是不一样的。

CREATE OR REPLACE procedure p_test is
  v_sdate varchar2(10);
  v_tablename varchar2(200);
  v_sql_tabledate varchar2(4000);  
  TYPE cur IS REF CURSOR;
  c cur;  


TYPE tr IS RECORD (
       id NUMBER,vname VARCHAR2(20)
       );
  v_c  tr;

begin
    select to_char(sysdate,'mmdd') into v_Sdate from dual;
    v_tablename := 'T_'||v_sdate||'SUBMITFAILEDHISTORY';   

    v_sql_tabledate := 'select id,vname from '|| v_tablename ||' where id = 1';
    OPEN c FOR v_sql_tabledate;
        loop
                fetch c into v_c;   
                Exit when c%not found;         
                dbms_output.put_line(v_c.id);        
                dbms_output.put_line(v_c.vname);        
        end loop;
        close c;
end p_test;
/
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-11 21:48 | 显示全部楼层
说明下。我的表A可能是3列,表B可能是2列,并且列名都有可能不同。

使用道具 举报

回复
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2018-10-11 22:20 | 显示全部楼层
如果连结构都不固定,你就不可能写静态的代码来消费这些数据(比如上面的DBMS_OUTPUT.PUT_LINE)。因为你都不知道要访问什么列名。
这样的需求是罕见的。请详细说明为什么要这么做,需要达到什么目的。

使用道具 举报

回复
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-11 22:25 | 显示全部楼层
我有看到类似的例子。明天再研究下。(Oracle PL/sql实战第二章)
20181011222341.png



使用道具 举报

回复
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2018-10-12 00:01 | 显示全部楼层
fjzsl 发表于 2018-10-11 22:25
我有看到类似的例子。明天再研究下。(Oracle PL/sql实战第二章)

看到了吧,这段代码是全动态的PL/SQL,这种复杂代码是很难阅读和维护的。它也只能做一些通用的需求,比如把一张表的所有列原封不动复制到另一张。
所以,先搞清楚自己的需求,是否有必要用这么复杂的代价来实现。

使用道具 举报

回复
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-12 17:19 | 显示全部楼层
还想请教下,动态SQL如何传递变量。如下所示。提示:ORA-01006: 绑定变量不存在
20181012171628.png


谢谢newkid

使用道具 举报

回复
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-12 20:44 | 显示全部楼层
l_table_name :=p_table_name;

  v_sql :=
'DECLARE '||
'    l_table_name varchar2(200);'||
'       v_row '||p_table_name||'%ROWTYPE;'||
'  l_ipo_log         ipo_import_log%ROWTYPE;'||
'    begin '||
'for c in (select * INTO v_row from '||p_table_name|| ' WHERE import_code ='||g_item_code||') loop'||
' l_ipo_log.import_code:=c.import_code; '||
' l_ipo_log.row_id:=c.row_id; '||

' l_ipo_log.table_name:= l_table_name; '||
' l_ipo_log.Insert_Update_Status:=c.insert_update_status; '||
' l_ipo_log.creation_date:=sysdate; '||
' ipo_public_pkg.insert_ipo_log(l_ipo_log); '||
' end loop;'||
   ' end;';

  execute immediate v_sql using l_table_name;

使用道具 举报

回复
论坛徽章:
526
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2018-10-12 21:32 | 显示全部楼层
你的l_table_name既然是要传进去,就不要在动态PLSQL中声明。另外g_item_code的用法是很恶劣的,这里也应该用绑定变量。

  v_sql :=
'DECLARE '||
'   --- l_table_name varchar2(200);'|| ----------------这个应该去掉
'       v_row '||p_table_name||'%ROWTYPE;'||
'  l_ipo_log         ipo_import_log%ROWTYPE;'||
'    begin '||
'for c in (select * INTO v_row from '||p_table_name|| ' WHERE import_code =:g_item_code) loop'|| ------------ 这里改用绑定变量占位符
' l_ipo_log.import_code:=c.import_code; '||
' l_ipo_log.row_id:=c.row_id; '||

' l_ipo_log.table_name:= :l_table_name; '|| ------------ 这里改用绑定变量占位符
' l_ipo_log.Insert_Update_Status:=c.insert_update_status; '||
' l_ipo_log.creation_date:=sysdate; '||
' ipo_public_pkg.insert_ipo_log(l_ipo_log); '||
' end loop;'||
   ' end;';


execute immediate v_sql using g_item_code,l_table_name;   

使用道具 举报

回复
认证徽章
论坛徽章:
1
秀才
日期:2017-04-05 13:18:06
发表于 2018-10-12 22:41 | 显示全部楼层
非常感谢版主。搞定了,学习了很多。。。感谢。。。。。。。。。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表