oracle实现动态sql的拼装要领
来源: 阅读:768 次 日期:2016-06-14 10:44:39
温馨提示: 小编为您整理了“oracle实现动态sql的拼装要领”,方便广大网友查阅!

这篇文章主要介绍了oracle实现动态sql的拼装要领,对于oracle的进一步学习来说非常重要,需要的朋友可以参考下。

虽说oracle的动态sql语句使用起来确实很方便,但是其拼装过程却太麻烦。尤其在拼装语句中涉及到date类型字段时,拼装时要加to_char先转换成字符,到了sql中又要使用to_date转成date类型和原字段再比较。

例如有这样一个sql语句:

select '========= and (t.created>=to_date('''||to_char(sysdate,'yyyy-mm-dd')||''',''yyyy-mm-dd'') and t.created< to_date('''||to_char(sysdate+1,'yyyy-mm-dd')||''',''yyyy-mm-dd''))' from dual;

它就是将sysdate转成字符串,再在生成的sql中将字符串转换成date。

其拼装出来的结果如下:

========= and (t.created>=to_date('2012-11-08','yyyy-mm-dd') and t.created< to_date('2012-11-09','yyyy-mm-dd'))

字符串2012-11-08是我们使用to_char(sysdate,'yyyy-mm-dd')生成的,语句中涉及到的每一个单引号,都要写成两个单引号来转义。

虽然拼装过程很烦人,但只要掌握好三点,就应能拼装出能用的sql语句。

一、先确定目标。应保证拼装出来的sql应该是什么样子,然后再去配置那个动态sql

二、拼装sql的时候,所有使用连接符||连接的对象都应是varchar2类型,这种类型的对象以单引号开头,以单引号结尾。数字会自动转,但date需要我们手工使用to_char函数转。

三、遇到有引号的,就写成两个单引号。

如 ' i am a sql developer '' '||v_name||' '' in china. telephone is '||v_number||' .'

v_name是字符型的,所以拼装它是需要前后加单引号。

这种转换很烦人,但从10g开始有一个新功能,可以让人不用这么烦。它就是q'[xxxxx]'

代码如下:

select q'[ i'm a sql developer ' ]'||to_char(sysdate,'yyyy')||q'[' in china. telephone is ]'||1990||'.' from dual;

代码如下:

1 i'm a sql developer '2012' in china. telephone is 1990.

i'm使用一个单引号在q'[]'中就可以。

to_char(sysdate,'yyyy')转成的是2012,前后是要加单引号的。所以在q'[xxx ']'的结尾加了一个单引号。

这样就使得我们不用想以前那样使用 ''''表示一个单引号了。

简而言之,掌握这三点,就应该能拼装出能用的sql。至于如果使用绑定变量输入输出,则需要使用into using关键字。

set serveroutput on;

declare

incoming date:=sysdate-10;

outgoing int;

begin

execute immediate 'select count(*) from user_objects where created > :incoming' into outgoing using incoming ;

dbms_output.put_line(' count is: ' || outgoing);

end;

使用using的好处,就是不用去转date类型为varchar类型,再转回去date类型这种繁琐的操作。

代码如下:

declare

incoming date:=sysdate-10;

outgoing int;

begin

execute immediate 'insert into t_object(a) select count(*) from user_objects where created > :incoming' into outgoing using incoming ;

dbms_output.put_line(' count is: ' || outgoing);

end;

ora-01007: 变量不在选择列表中

ora-06512: 在 line 6

tom这样解释这个错误:followup    november 24, 2004 - 7am central time zone:

 you have to use dbms_sql when the number of outputs is not known until run time.

代码如下:

declare

v_cursor number; --定义游标

v_string varchar2(2999);

v_row number;

begin

v_string := 'insert into t_object(a) select count(*) from user_objects where created > :incoming';--操作语句,其中:name是语句运行时才确定值的变量

v_cursor:=dbms_sql.open_cursor;--打开处理游标

dbms_sql.parse(v_cursor,v_string,dbms_sql.native);--解释语句

dbms_sql.bind_variable(v_cursor,':incoming',sysdate-30); --给变量赋值

v_row := dbms_sql.execute(v_cursor);--执行语句

dbms_sql.close_cursor(v_cursor);--关闭游标

--dbms_output.put_line(v_row);

commit;

exception

when others then

dbms_sql.close_cursor(v_cursor); --关闭游标

rollback;

end;

更多信息请查看脚本栏目
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map