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;
猜你喜欢
- 首先看一下super()函数的定义:super([type [,object-or-type]])Return a **proxy obje
- 导语昨天看到有留言竟然说我是月更博主,我明明更新地这么勤快(心虚.jpg)。看吧,昨天刚更新过,今天又来更新了。今天还是带大家写个小游戏吧,
- MYSQL初学者使用指南与介绍 一、连接MYSQL。 格式: mysql -h主机地址 -u用户名 -p用户密码 1、例1:连接到本机上的M
- 今天来分享一下图,这是一种比较复杂的非线性数据结构,之所以复杂是因为他们的数据元素之间的关系是任意的,而不像树那样 被几个性质定理框住了,元
- 1,不用第三方库# coding: utf-8import loggingBLACK, RED, GREEN, YELLOW, BLUE,
- 需求: 一台机器上有多个网卡, 如何访问指定的 URL 时使用指定的网卡发送数据呢?$ curl --interface eth0 www.
- 代码如下:vbcrlfvbs常量相当于vbcr & vblf 就是常见的那个 chr(13) & chr(10),用Chr(
- 利用python pyheatmap包绘制热力图,供大家参考,具体内容如下import matplotlib.pyplot as pltfr
- python中支持SSH协议的模块主要有Paramiko和netmiko两种,本次实验采用netmiko模块。netmikko模块为pyth
- 看了不少朋友的个人网站,有一个小问题,似乎很多朋友都忽略了,那就是版权声明的写法。虽然那只是一小行字,不过作为设计师也好,作为个人的爱好也好
- 这篇文章主要介绍了Python基于内置库pytesseract实现图片验证码识别功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具
- 本文实例讲述了朴素贝叶斯分类算法原理与Python实现与使用方法。分享给大家供大家参考,具体如下:朴素贝叶斯分类算法1、朴素贝叶斯分类算法原
- 本文实例讲述了python和bash统计CPU利用率的方法。分享给大家供大家参考。具体如下:开始的时候写了一个 bash 的实现;因为最近也
- 装饰器通用模型def wrapper(fn): def inner(*args, **kwargs):  
- 本文实例为大家分享了js实现简单贪吃蛇效果的具体代码,供大家参考,具体内容如下上代码之前,先给大家看一下效果:是不是想说:我能这样玩一天…话
- 本脚本为本人在性能测试过程中编写,用于对进程状态的监控,也可以用于日常的监控,适用性一般,扩展性还行# -*- coding: UTF-8
- 定义字典 dic = {'a':"hello",'b':"how",
- 在分析python的参数传递是如何进行的之前,我们需要先来了解一下,python变量和赋值的基本原理,这样有助于我们更好的理解参数传递。py
- 前言很多文章在谈及曲线平滑的时候,习惯使用拟合的概念,我认为这是不恰当的。平滑后的曲线,一定经过原始的数据点,而拟合曲线,则不一定要经过原始
- 看过数据库的备份与还原。大多数都是用组件来完成的。其实可通过sql语句来完成。 由于时间关系,未对参数进行验证和界面美化。代码