Oracle实现动态SQL的拼装要领

作者:shichen2014 时间:2024-01-15 07:38:23 

虽说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;

结果如下:


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类型这种繁琐的操作。

SQL代码如下: 


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.
 
Sql代码如下:


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;
标签:Oracle,动态SQL,拼装,要领
0
投稿

猜你喜欢

  • kafka rabbitMQ及rocketMQ队列的消息可靠性保证分析

    2022-05-06 08:10:23
  • JavaScript在ASP页面中实现掩码文本框效果代码

    2013-06-01 19:57:23
  • Python中的is和id用法分析

    2021-12-09 17:23:12
  • Python语法学习之进程间的通信方式

    2023-04-03 11:30:28
  • 解决Can't find variable: SockJS vue项目的问题

    2024-04-27 16:07:50
  • 详解MySQL Workbench使用教程

    2024-01-27 04:37:55
  • django中瀑布流写法实例代码

    2022-08-04 11:11:26
  • 判断python字典中key是否存在的两种方法

    2023-08-19 00:18:05
  • MySQL mysqladmin客户端的使用简介

    2024-01-26 00:33:29
  • 如果你有这33种症状了请离开电脑去走走吧!

    2022-11-07 18:17:21
  • 为什么在MySQL中不建议使用UTF-8

    2024-01-25 17:53:29
  • 使用NotePad++录制宏功能如何快速将sql搜索条件加上前后单引号

    2024-01-23 19:29:37
  • python神经网络特征金字塔FPN原理

    2023-12-20 02:21:01
  • python使用datetime模块计算各种时间间隔的方法

    2021-11-28 05:31:35
  • 使用Python三角函数公式计算三角形的夹角案例

    2022-12-06 04:09:33
  • Vue过滤器的用法和自定义过滤器使用

    2024-05-09 10:41:20
  • 在Linux下搭建Git服务器的方法详解

    2022-02-05 16:35:10
  • pymongo实现多结果进行多列排序的方法

    2023-08-27 21:33:42
  • SQL数据库优化大总结之百万级数据库优化方案

    2024-01-16 09:42:10
  • PyTorch预训练Bert模型的示例

    2021-11-12 14:31:39
  • asp之家 网络编程 m.aspxhome.com