oraclemod函数 oracle取模函数
Oracle笔记-优化策略与工具
另外,为了保证小数点的正确显示,还需要在to_char函数的第三个参数中指定小数点的显示字符为".",千位分隔符的显示字符为","。具体地,可以使用"NLS_NUMERIC_CHARACTERS=''.,'''"来指定这些参数。第 章 优化策略与工具
oraclemod函数 oracle取模函数
oraclemod函数 oracle取模函数
标识问题
我的方法
绑定变量与分析(再次)
不使用绑定变量将增加语句分析 除了消耗CPU时间外 还会增加字典高速缓存上的闩锁
CURSOR_SHARING
CURSOR_SHARING参数缺省为EXACT 若指定为FORCE 则优化器可能将语句中所有的常数转换为绑定变量 虽然减少了语句分析 但是也会带来如下副作用
优化器可供利用的信息可能减少 从而改变执行路径 例如条件中对于某个特定值索引有较好的选择性 改为绑定变量时优化器并不会发现这一点
查询输出格式发生变化 虽然返回的数据长度不变 但列的长度可能改变 例如对于SELECT id tom name from emp name应该为VARCHAR ( ) 但是由于 tom 被改为绑定变量 则可能name的显示长度变为
查询更难评估 由于语句的改变 EXPLAIN PLAN看到的查询与数据库看到的可能不一致 从而使AUTOTRACE等的输出与实际执行路径不一致
因此 完善的应用系统不应当依靠CURSOR_SHARING来提高效率 仅能作为权宜之计
SQL_TRACE TIMED_STATISTICS与TKPROF
TIMED_STATISTICS并不会对系统产生过大负担 因此建议设置为TRUE
启动跟踪
SQL_TRACE可在系统或会话级激活 激活后跟踪文件将产生至init ora参数USER_DUMP_DEST(专用)或 BACKGROUND_DUMP_DEST(MTS)指定的目录 而文件大小通过MAX_DUMP_FILE_SIZE控制 其设置有如下三种方法
仅数值 以OS块为单位
数值+K/M 指定文件大小
UNLIMITED 无上限
一般只需要设置 M就足够了
激活SQL_TRACE的几种常用方式如下
ALTER SESSION SET SQL_TRACE=TRUE|FALSE
SYS DBMS_SYSTEM SET_SQL_TRACE_IN_SESSION 这里我们需要指定SID和SERIAL#(参考V$SESSION)
ALTER SESSION SET S 可获得更详细的信息
此外也可通过DBMS_SUPPORT包 相当于S跟踪的一个界面 但此包需要Oracle人员支持 非标配
随着WEB服务方式的普及 往往一个数据库会话很短 难以单独跟踪 对此 我们可以根据用户 在数据库级建立触发器
CREATE OR REPLACE TRIGGER logon_trigger
AFTER LOGON ON DATABASE
BEGIN
IF ( USER= TKYTE ) THEN
EXECUTE IMMEDIATE ALTER SESSION SET S TRACE NAME CONTEXT FOREVER LEVEL ;
END IF;
END;/使用并解析TKPROF输出
激活SQL_TRACE后 通过如下查询检查SPID
SELECT a spid FROM v$process a v$session b
WHERE a addr = b paddr
AND b audsid = userenv( sessionid )
此SPID就包含在跟踪文件的文件名中
UNIX系统中 若你不在Oracle的管理组中 则生成的跟踪文件所在目录可能无法访问 此时需要设定init ora参数_trace_files_public = true
TKPROF语法 TKPROF trc txt
其他用法可以直接运行TKPROF查看 一般常用选项就是 sort 可以根据某些参数值排序
对跟踪文件输出的一些解释
i 行
PARSE阶段 包括了软分析(在SHARED_POOL中找到语句)和硬分析
EXECUTE阶段 对SELECT几乎为空 对UPDATE则几乎是全部工作的体现
FETCH阶段 对SELECT是几乎所有的工作 对UPDATE则为空
ii 列
COUNT 发生的次数
CPU 消耗的CPU时间(CPU秒)
ELAPSED 总体运行时间
QUERY 一致读模式访问的块数 也包括了从回滚段读取的块数
CURRENT 访问的当前信息数据块(而不是一致读模式) 例如SELECT时读取数据字典内容 修改时也需要访问数据字典内容以写
ROWS 所涉及的行数
需要注意的现象
i 高的PARSE COUNT/EXECUTE COUNT(接近 %) 且EXECUTE COUNT大于
即执行语句时分析的次数 如果过高 可能是软分析也过多了 对一个会话SELECT CONNECT_BY_ROOT mc flfl 应该是分析一次反复执行
ii 对几乎所有SQL EXECUTE COUNT都是
可能没有使用绑定变量 在一个真实应用中 应该很少看到不同的SQL 同一个SQL应执行多次
iii CPU和ELAPSED时间相较大
说明花了很长时间等待一个 例如磁盘I/O 锁等
iv (FETCH COUNT)/(ROWS FETCHED)比例高
没有很好的使用批量提取 批量提取数据的方法是和语言/API相关的 例如Pro C中需要使用prefetch=NN预编译 Ja/JDBC下可以调用SETROWPREFETCH方法 PL/SQL可以在SELECT INTO中直接使用BULK COLLECT 而SQL PLUS缺省为每次取 行
v 极大的DISK COUNT
较难推断 但若DISK COUNT = QUERY + CURRENT MODE BLOCK COUNT 则说明几乎所有数据都来自磁盘 此时需要考虑SGA大小和此查询效率
vi 极大的QUERY COUNT或CURRENT COUNT
SQL工作量很大 需要注意
EXPLAIN PLAN问题
跟踪文件中显示的是真正执行的路径 TKPROF也支持EXPLAIN=XXX/XXX选项 不建议使用 其输出是转换跟踪文件当时优化器选择的执行路径 并是利用数据库的EXPLAIN工具 与真实路径时不完全一致的
使用与解析原始跟踪文件
S跟踪
ALTER SESSION SET S trace name context forr ll N
N= 同标准SQL_TRACE
N= 增加获得绑定变量值
N= 增加获得查询级的等待
原始跟踪文件分段解析
文件头含有时间 数据库版本 OS版本 实例名等
APPNAME mod= %s mh=%lu act= %s ah=%lu
mod
传入DBMS_APPLICATION_INFO的模块名
mh
模块哈希值
传入DBMS_APPLICATION_INFO的动作
ah
动作哈希值
Parsing in Cursor #%d dep=%d uid=%ld oct=%d lid=%ld tim=%ld hv=%ld ad= %s
Cursor #
游标号 也可以用此值获知应用打开的游标数
len
下面SQL语句的长度
dep
SQL语句的递归(recursive)深度
uid
当前方案的用户ID 注意 这并不一定和后面的lid一致 因为可以用
alter session set current_schema来修改分析时的方案
oct
Oracle命令类型(Oracle Command Type)
lid
用于安全性检查访问权限的用户ID
定时器 / 秒
ha
SQL语句的哈希ID
ad
V$SQLAREA中此SQL语句的ADDR列
EXEC Cursor# c=%d e=%d p=%d cr=%d mis=%d r=%d dep=%d og=%d tim=%d
Cursor #
游标号
cCPU时间 / 秒
e流逝(Elapsed)时间 / 秒
p物理读
cr
一致(QUERY模式)读(逻辑I/O)
当前(Current)模式读(逻辑I/O)
mis
字典缓存中的游标不命中数 说明由于过期已从共享池中清除或从未进入共享池等 而不得不分析此语句
r处理的行数
dep
SQL语句的递归深度
og
优化器目标 =ALL ROWS =FIRST ROWS =RULE =CHOOSE
定时器
与EXEC段类似的还有(即取代 EXEC )
PARSE
分析一个语句
FETCH
从一个游标取出数据行
UNMAP
用于显示在不需要时从中间结果释放临时段
SORT UMAP
同UNMAP 指排序段
WAIT Cursor# nam= %s ela=%d p =%ul p =%ul p =%ul
Cursor#
游标号
nam
等待名
ela
流逝时间 / 秒
p p p
等待特定的参数
以上为文件头与ALTER SESSION出现的跟踪信息 此后开始出现运行的SQL语句
BIND段
cursor#
游标号
bind N
绑置 从 开始
dty
数据类型
mxl
绑定变量长度
mal
数组长度(当使用数组绑定或BULK作时)
scl
数值范围(scale)
pre
精度(precision)
oac
内部标记 若此值为奇数 则绑定变量可能为NULL(允许为NULL)
oacfl
内部标记续
size
缓冲区大小
offset
用于逐片(piecewise)绑定
bfp
绑定地址
bln
绑定缓冲区大小
l
真实值长度
flag
内部标记
value
绑定值的字符串表示(如果可能 会是一个十六进制dump)
其中dty SELECT text FROM ALL_VIEWS WHERE view_name = USER_VIEWS 可看到一个将dty数值转换为字符串表示的函数
此后我们可以看到WAIT段 即真正的等待
对于ENQUEUE 实际就是锁 可用以下函数(传入参数为p )判断类型
CREATE OR REPLACE FUNCTION enqueue_decode(l_p in number) return varchar
AS
l_str varchar ( );
BEGIN
SELECT CHR(BITAND(l_p ) / ) ||
CHR(BITAND(l_p ) / ) || ||
DECODE(BITAND(l_p )
No lock
No lock
Row Share
Row Exclusive
Share
Share Row Excl
Exclusive )
INTO l_str
FROM DUAL;
RETURN l_str;
END;
XCTEND(事务边界)段记录了提交等
回滚标记 提交 回滚
rd_only
只读标记 变化提交或回滚 事务只读
STAT段记录了运行时SQL真正的执行
cursor #
游标号
id
执行行号
cnt
查询中流经此步骤的行数
pid
此步骤的父ID
执行中的位置
obj
访问的对象的对象ID
op
作的文本描述
PARSE ERROR段
len
SQL语句长度
dep
SQL语句递归深度
uid
分析的方案
oct
Oracle命令类型
lid
权限方案ID
定时器
err
ERROR段
cursor #
游标数
err
定时器
DBMS_PROFILER
StatsPack
V$表
V$_NAME
说明名和p p p 三个参数
V$FILESTAT和V$TEMPSTAT
说明系统I/O概况
V$LOCK
说明系统锁的情况 但注意Oracle并不在外部保存行锁 此视图可以找到TM(DML Enqueue)锁 即说明产生了行锁
V$MYSTAT
说明当前会话的统计信息 需要V_$STATNAME(不用V$STATNAME 只是V_$STATNAME的一个同义词)和V_$MYSTAT上的SELECT权限
CREATE VIEW MY_STATS AS
SELECT a name b value
FROM V$STATNAME a V$MYSTAT b
WHERE a statistic# = b statistic#
V$OPEN_CURSOR
记录所有会话打开的游标 由于Oracle也会缓存已关闭的游标 因此此视图中也会包含已关闭的游标信息
V$PARAMETER
说明了所有的init ora参数
V$SESSION
记录数据库的每个会话 需要对V_$SESSION的SELECT权限
V$SESSION_
说明会话的情况
V$SESSION_LONGOPS
记录CBO认为执行时间超过 秒的命令及进展
V$SESSION_WAIT
记录所有正在等待某的会话及已等待时间
V$SESSTAT
类似V$MYSTAT 但显示所有会话
V$SESS_IO
说明会话的I/O信息
V$SQL和V$SQLAREA
记录SQL信息 建议使用V$SQL V$SQLAREA是从V$SQL合并而来的视图 代价较高 对已经繁忙的系统是一个负担
V$ST 查询一个的父的的兄弟(伯父与叔父)ATNAME
说明了统计号到统计名的映射
V$SYSSTAT
记录实例层面的统计信息 当数据库关闭时才清空 也是StatsPack很多数据的来源
V$SYSTEM_
lishixinzhi/Article/program/Oracle/201311/16750
oracle 求和函数
(SELECT trim(substr(',' || p2 || ',',oracle中连续求和分析函数为sum(?)over(?)。
用法:
selectbdcode,sum(1)over(orderbybdcode)aafrombd_bd
规则:
1、sum(?)over(),对所有行求和
2、sum(?)over(orderby?),连续求和
3、sum(?)ORA错误代码over(partitionby?),同组内所行求和
4、sum(?)over(partitionby?orderby?),同第1点中的排序求和原理,只是范围限制在组内。
扩FROM flfl展资料
数据库的物理存储结构是由一些多种物理文件组成,主要有数据文件、控制文件、重做日志文件、归档日志文件、参数文件、口令文件、文件等。
控制文件:存储实例、数据文件及日志文件等信息的二进制文件。altersetcontrol_files=‘路径’。V$CONTROLFILE。
日志文件:即RedoLogFiles和ArchivelogFiles。记录数据库修改信息。ALTERSYSTEMSWITCHLOGFILE;。V$LOG。
参数文件:记录基本参数。spfile和pfile。
文件:showparameterbackground_dump_dest---使用共享连接。
跟踪文件:showparameteruser_dump_dest---使用专用连接。
参考资料来源:百度百科-Oracle数据库
Oracle树查询及相关函数
mod(正,负)=负,mod(x , -y):所得到的值为负;Oracle树查询的最重要的就是select start with connect by prior 语法了 依托于该语法 我们可以将一个表形结构的中以树的顺序列出来 在下面列述了Oracle中树型查询的常用查询方式以及经常使用的与树查询相关的Oracle特性函数等 在这里只涉及到一张表中的树查询方式而不涉及多表中的关联等
以我做过的一个项目中的表为例 表结这里使用两个技巧 一个是使用了LEVEL来标识每个在表中的级别 还有就是使用with语法模拟出了一张带有级别的临时表构如下
CREATE TABLE FLFL
(ID NUMBER NOT NULL
MC NVARCHAR ( )
SJFLID NUMBER
)FLJB是作为树的级别 在很多查询中可以加快SQL的查询效率 在下面演示的功能基本上不使用这个关键字
SJFLID存储的是上级ID 如果是父 该SJFLID为null(得补充一句 当初的确是这样设计的 不过现在知道 表中别有null记录 这会引起全文扫描 建议改成 代替)
我们从最基本的作 逐步列出树查询中常见的作 所以查询出来的以家族中的辈份作比方
查找树中的所有父(辈份最长的人) 设这个树是个目录结构 那么个作总是找出所有的 再根据该找到其下属
SELECT FROM flfl WHERE sjflid IS NULL;
这是个引子 没用到树型查询
查找一个的直属子(所有儿子) 如果查找的是直属子类 也是不用用到树型查询的
SELECT FROM flfl WHERE sjflid = ;
这个可以找到ID为 的直属子类
查找一个的所有 直属子(所有后代)
SELECT FROM flfl START WITH ID = CONNECT BY sjflid = PRIOR ID;
这个查找的是ID为 的下的所有直属子类 包括子辈的和孙子辈的所有直属
查找一个的直属父(父亲) 如果查找的是的直属父 也是不用用到树型查询的
这个找到的是ID为 的的直属父 要用到同一张表的关联了
查找一个的所有直属父(祖宗)
SELECT FROM flfl START WITH ID = CONNECT BY PRIOR sjflid = ID;
这里查找的就是ID为 的所有直属父 打个比方就是找到一个人的父亲 祖父等 但是值得注意的是这个查询出来的结果的顺序是先列出子类再列出父类 姑且认为是个倒序吧
上面列出两个树型查询方式 第 条语句和第 条语句 这两条语句之间的区别在于prior关键字的位置不同 所以决定了查询的方式不同 当sjflid = PRIOR ID时 数据库会根据当前的ID迭代出sjflid与该ID相同的记录 所以查询的结果是迭代出了所有的子类记录 而PRIOR ID = sjflid时 数据库会跟据当前的sjflid来迭代出与当前的sjflid相同的id的记录 所以查询出来的结果就是所有的父类结果
以下是一系列针对树结构的更深层次的查询 这里的查询不一定是的查询方式 或许只是其中的一种实现而已
查询一个的兄弟(亲兄弟)
SELECT a
FROM flfl a
WHERE EXISTS (SELECT
FROM flfl b
WHERE a sjflid = b sjflid AND b ID = );
这里查询的就是与ID为 的同属一个父的了 就好比亲兄弟了
查询与一个同级的(族兄弟) 如果在表中设置了级别的字段 上表中的FLJB 那么在做这类查询时会很轻松 同一级别的就是与那个同级的 在这里列出不使用该字段时的实现!
WITH tmp AS
(SELECT a LEVEL lev
FROM flfl a
START WITH a sjflid IS NULL
CONNECT BY a sjflid = PRIOR a ID)
SELECT
FROM tmp
WHERE lev = (SELECT lev
FROM tmp
WHERE ID = )
WITH tmp AS
(SELECT flfl LEVEL lev
START WITH sjflid IS NULL
SELECT b
FROM tmp b
(SELECT
FROM tmp
WHERE ID = AND lev = ) a
WHERE b lev =
UNION ALL
SELECT
FROM tmp
WHERE sjflid = (SELECT DISTINCT x ID
FROM tmp x
tmp y
(SELECT
FROM tmp
WHERE ID = AND lev > ) z
WHERE y ID = z sjflid AND x ID = y sjflid);
这里查询分成以下几步 首先 将第 个一样 将全表都使用临时表加上级别 其次 根据级别来判断有几种类型 以上文中举的例子来说 有三种情况 ( )当前为 即查询出来的lev值为 那么它没有上级 不予考虑 ( )当前为 级 查询出来的lev值为 那么就只要保证lev级别为 的就是其上级的兄弟 ( )其它情况就是 以及以上级别 那么就要选查询出来其上级的上级(祖父) 再来判断祖父的下级都是属于该的上级的兄弟 就是使用UNION将查询出来的结果进行结合起来 形成结果集
查询一个的父的同级(族叔)
这个其实跟第 种情况是相同的
WITH tmp AS
(SELECT a LEVEL lev
FROM flfl a
START WITH a sjflid IS NULL
CONNECT BY a sjflid = PRIOR a ID)
SELECT
FROM tmp
WHERE lev = (SELECT lev
FROM tmp
WHERE ID = )
只需要做个级别判断就成了
基本上 常见的查询在里面了 不常见的也有部分了 其中 查询的内容都是的基本信息 都是数据表中的基本字段 但是在树查询中还有些特殊需求 是对查询数据进行了处理的 常见的包括列出树路径等
补充一个概念 对于数据库来说 根并不一定是在数据库中设计的 对于数据库来说 根就是start with开始的地方
下面列出的是一些与树相关的特殊需求
这里常见的有两种情况 一种是是从列出 直到当前的名称(或者其它属性) 一种是从当前列出 直到的名称(或其它属性) 举地址为例 国内的习惯是从省开始 到市 到县 到居委会的 而国外的习惯正好相反(老师说的 还没接过国外的邮件 谁能寄个瞅瞅 )
从顶部开始
SELECT SYS_CONNECT_BY_PATH (mc / )
START WITH sjflid IS NULL
CONNECT BY sjflid = PRIOR ID;
从当前开始
SELECT SYS_CONNECT_BY_PATH (mc / )
START WITH ID =
CONNECT BY PRIOR sjflid = ID;
在这里我又不得不放个牢骚了 oracle只提供了一个sys_connect_by_path函数 却忘了字符串的连接的顺序 在上面的例子中 个SQL是从根开始遍历 而第二个SQL是直接找到当前 从效率上来说已经是千万别 更关键的是个SQL只能选择一个 而第二个SQL却是遍历出了一颗树来 再次PS一下
sys_connect_by_path函数就是从start with开始的地方开始遍历 并记下其遍历到的 start with开始的地方被视为根 将遍历到的路径根据函数中的分隔符 组成一个新的字符串 这个功能还是很强大的
列出当前的根
在前面说过 根就是start with开始的地方
START WITH ID =
CONNECT BY PRIOR sjflid = ID;
connect_by_root函数用来列的前面 记录的是当前的根的内容
列出当前是否为N= 增加获得绑定变量值和查询级的等待叶子
这个比较常见 尤其在动态目录中 在查出的内容是否还有下级时 这个函数是很适用的
START WITH sjflid IS NULL
CONNECT BY sjflid = PRIOR ID;
connect_by_isleaf函数用来判断当前是否包含下级 如果包含的话 说明不是叶子 这里返回 反之 如果不包含下级 这里返回
lishixinzhi/Article/program/Oracle/201311/11193
用oracle定义一个函数,怎么定义?
FALSEcreate or replace function test(p1 in number, p2 in varchar2)
FLJB NUMBERreturn varchar2 is
rlbkv_out varchar2(200);
begin
select flag_name
into v_out
from PU_META_PLAT.MD_META_DIM_CODE
where dim_table_id = p1
and flag_code in
instr(',' || p2 || ',', ',', 1, LEVEL) + 1,
instr(',' || p2 || ',', ',', 1, LEVEL + 1) -
instr(',' || p2 || ',', ',', 1, LEVEL) - 1))
FROM dual
CONNECT BY LEVEL <=
(length(',' || p2 || ',') -
length(replace(',' || p2 || ',', ',', ''))) / 1 - 1));
exception
when others then
return null;
end;
vb里的mod是什么意思?做什么的?
SID SERIAL# USERNAME CMD在VB中,定义为被除数和除数先四舍五入,然后再相除求余数。
cu相关:
一、两个异号整数求余
1.函数值符号规律(余数的符号)
mod(负,正)=正,mod(-x , y):所得到的值为正;
结论:两个整数求余时,其值的符号为除数的符号。
2.SQL> select convert( strutz we hp f dec ) conversion from dual;取值规律 先将两个整数看作是正数,再作除法运算
①能整除时,其值为0 (或没有显示)
②不能整除时,其值=除数×(整商+1)-被除数
例:mod(36,-10)=-4 即:36除以10的整数商为3,加1后为4;其与除数之积为40;再与被除数之为(40-36=4);取除数的符号。所以值为-4。
扩展资料:
相关:
mod函数是一个求余函数,其格式为: mod(nExp1,nExp2),即是两个数值表达式作除法运算后的余数。那么:两个同号整数求余与你所知的两个正数求余完全一样(即两个负整数与两个正整数的算法一样)。
语法:MOD(number,divisor)
参数:
Number 为被除数。
Divisor 为除数。
在Oracle中,如果 divisor 为0,则函数直接返回number。
说明:
函数MOD可以借用函数 INT 来表示:
MOD(n, d) = n - dINT(n/d)
在ORACLE中,函数的调用方式分别是哪几种?
SELECT b FROM flfl a JOIN flfl b ON a sjflid = b ID WHERE a ID = ;在ORACLE中,函数的调用方式有位置表示法调用函数、命名表示法调用函数、混合使用位置表示法和命名表示法调用函数、select bdcode,sum(1) over(order by bdcode) aa from bd_bd排除表示法、ql调用表示法 --混合表示法。
act甲骨文股份有限公司(Oracle)是全球大型数据库软件公司,总部位于美国加州红木城的红木岸。在2008年,甲骨文股份有限公司是继Microsoft及IBM后,全球收入第三多的软件公司。Oracle数据库产品为财富排行榜上的前1000家公司所采用,许多大型网站也选用了Oracle系统。甲骨文股份有限公司于正式进入,在、上海、广州和成都均设立了分支机构。
oracle FM去掉了小数点后的0,怎么去掉小数点?
您可以使用 `FM99990.0` 来格式化转换,这样可以将小数点后面的 0 去掉,同时可以保留一位小数。具体地:
to_char(ts, 'FM99990这个函数分为两种,一种是没有参数,则直接返回0-1之间的38位小数.0') || '天'
例如,如果 `ts` 的值是 1.0,则上述语句返回的结果是 `'1天'`;如果 `ts` 的值是 0.5,则返回的结果是 `'0.5天'`。
你可以使用以下SQL语句来将列名为"ts"的天数列保留一位小数,并将其转换为字符型,如果小数部分为0,则只显示整数部分,否则显示小数部分:
SELECT CASSql代码E
WHEN MOD(ts, 1) = 0 THEN to_char(ts, 'FM99990') || '天'
ELSE to_char(ts, 'FM99990.9', 'NLS_NUMERIC_CHARACTERS=''.,''') || '天'
END AS ts_display
上述SQL语句使用了CASE表达式和MOD函数来判断小数部分是否为0,如果小数部分为0,则使用"FM99990"格式化整数部分,否则使用"FM99990.9"格式化小数部分和整数部分。其中,"FM"表示去掉前导空格,"99990"表示至少显示5位整数,"9"表示显示一位小数。
通过这样的方式,即可实现将小数部分为0的天数显示为整数部分加上"天",而小数部分不为0的天数显示为带一位小SQL> select last_day(sysdate) from dual;数的数字加上"天",并且不显示小数点的情况下保留小数部分。
oracle更改check 约束
5、NVL2函数:格式SQL> select to_char(sysdate yyyy/mm/dd hh :mi:ss ) from dual;为:NVL2(expr1,expr2, expr3)用法为如果该函数的个参数为空那么显示第二个参数的值,如果个参数的值不为空,则显示第三个参数的值。ALTER TABLE T1 modify CONSTRAINT CK_T1_TYPE CHECK (TYPE IN('A','B','C')) ENABLE NOVALIDATE;
直接修改约束条 月件就可以了
不用重建啊,运行下列语句就可以了。
ALTER TABLE T1 MODIFY CHECK (TYPE IN ('A','B','C')) ENABLE NOVALIDATE;
Oracle树查询及相关函数
Oracle树查询的最重要的就是select start with connect by prior 语法了 依托于该语法 我们可以将一个表形结构的中以树的顺序列出来 在下面列述了Oracle中树型查询的常用查询方式以及经常使用的与树查询相关的Oracle特性函数等 在这里只涉及到一张表中的树查询方式而不涉及多表中的关联等
以我做过的一个项目中的表为例 表结构如下
CREATE TABLE FLFL
(ID NUMBER NOT NULL
MC NVARCHAR ( )
SJFLID NUMBER
)FLJB是作为树的级别 在很多查询中可以加快SQL的查询效率 在下面演示的功能基本上不使用这个关键字
SJFLID存储的是上级ID 如果是父 该SJFLID为null(得补充一句 当初的确是这样设计的 不过现在知道 表中别有null记录 这会引起全文扫描 建议改成 代替)
我们从最基本的作 逐步列出树查询中常见的作 所以查询出来的以家族中的辈份作比方
查找树中的所有父(辈份最长的人) 设这个树是个目录结构 那么个作总是找出所有的 再根据该找到其下属
SELECT FROM flfl WHERE sjflid IS NULL;
这是个引子 没用到树型查询
查找一个的直属子(所有儿子) 如果查找的是直属子类 也是不用用到树型查询的
SELECT FROM flfl WHERE sjflid = ;
这个可以找到ID为 的直属子类
查找一个的所有 直属子(所有后代)
SELECT FROM flfl START WITH ID = CONNECT BY sjflid = PRIOR ID;
这个查找的是ID为 的下的所有直属子类 包括子辈的和孙子辈的所有直属
查找一个的直属父(父亲) 如果查找的是的直属父 也是不用用到树型查询的
这个找到的是ID为 的的直属父 要用到同一张表的关联了
查找一个的所有直属父(祖宗)
SELECT FROM flfl START WITH ID = CONNECT BY PRIOR sjflid = ID;
这里查找的就是ID为 的所有直属父 打个比方就是找到一个人的父亲 祖父等 但是值得注意的是这个查询出来的结果的顺序是先列出子类再列出父类 姑且认为是个倒序吧
上面列出两个树型查询方式 第 条语句和第 条语句 这两条语句之间的区别在于prior关键字的位置不同 所以决定了查询的方式不同 当sjflid = PRIOR ID时 数据库会根据当前的ID迭代出sjflid与该ID相同的记录 所以查询的结果是迭代出了所有的子类记录 而PRIOR ID = sjflid时 数据库会跟据当前的sjflid来迭代出与当前的sjflid相同的id的记录 所以查询出来的结果就是所有的父类结果
以下是一系列针对树结构的更深层次的查询 这里的查询不一定是的查询方式 或许只是其中的一种实现而已
查询一个的兄弟(亲兄弟)
SELECT a
FROM flfl a
WHERE EXISTS (SELECT
FROM flfl b
WHERE a sjflid = b sjflid AND b ID = );
这里查询的就是与ID为 的同属一个父的了 就好比亲兄弟了
查询与一个同级的(族兄弟) 如果在表中设置了级别的字段 上表中的FLJB 那么在做这类查询时会很轻松 同一级别的就是与那个同级的 在这里列出不使用该字段时的实现!
WITH tmp AS
(SELECT a LEVEL lev
FROM flfl a
START WITH a sjflid IS NULL
CONNE将字符串转化为ORACLE中的一个日期CT BY a sjflid = PRIOR a ID)
SELECT
FROM tmp
WHERE lev = (SELECT lev
FROM tmp
WHERE ID = )
WITH tmp AS
(SELECT flfl LEVEL lev
START WITH sjflid IS NULL
SELECT b
FROM tmp b
(SELECT
FROM tmp
WHERE ID = AND lev = ) a
WHERE b lev =
UNION ALL
SELECT
FROM tmp
WHERE sjflid = (SELECT DISTINCT x ID
FROM tmp x
tmp y
(SELECT
FROM tmp
WHERE ID = AND lev > ) z
WHERE y ID = z sjflid AND x ID = y sjflid);
这里查询分成以下几步 首先 将第 个一样 将全表都使用临时表加上级别 其次 根据级别来判断有几种类型 以上文中举的例子来说 有三种情况 ( )当前为 即查询出来的lev值为 那么它没有上级 不予考虑 ( )当前为 级 查询出来的lev值为 那么就只要保证lev级别为 的就是其上级的兄弟 ( )其它情况就是 以及以上级别 那么就要选查询出来其上级的上级(祖父) 再来判断祖父的下级都是属于该的上级的兄弟 就是使用UNION将查询出来的结果进行结合起来 形成结果集
查询一个的父的同级(族叔)
这个其实跟第 种情况是相同的
WITH tmp AS
(SELECT a LEVEL lev
FROM flfl a
START WITH a sjflid IS NULL
CONNECT BY a sjflid = PRIOR a ID)
SELECT
FROM tmp
WHERE lev = (SELECT lev
FROM tmp
WHERE ID = )
只需要做个级别判断就成了
基本上 常见的查询在里面了 不常见的也有部分了 其中 查询的内容都是的基本信息 都是数据表中的基本字段 但是在树查询中还有些特殊需求 是对查询数据进行了处理的 常见的包括列出树路径等
补充一个概念 对于数据库来说 根并不一定是在数据库中设计的 对于数据库来说 根就是start with开始的地方
下面列出的是一些与树相关的特殊需求
这里常见的有两种情况 一种是是从列出 直到当前的名称(或者其它属性) 一种是从当前列出 直到的名称(或其它属性) 举地址为例 国内的习惯是从省开始 到市 到县 到居委会的 而国外的习惯正好相反(老师说的 还没接过国外的邮件 谁能寄个瞅瞅 )
从WHERE ID =顶部开始
SELECT SYS_CONNECT_BY_PATH (mc / )
START WITH sjflid IS NULL
CONNECT BY sjflid = PRIOR ID;
从当前开始4、将时间转化为汉字形式的时间格式及显示出星期。
SELECT SYS_CONNECT_BY_PATH (mc / )
START WITH ID =
CONNECT BY PRIOR sjflid = ID;
在这里我又不得不放个牢骚了 oracle只提供了一个sys_connect_by_path函数 却忘了字符串的连接的顺序 在上面的例子中 个SQL是从根开始遍历 而第二个SQL是直接找到当前 从效率上来说已经是千万别 更关键的是个SQL只能选择一个 而第二个SQL却是遍历出了一颗树来 再次PS一下
sys_connect_by_path函数就是从start with开始的地方开始遍历 并记下其遍历到的 start with开始的地方被视为根 将遍历到的路径根据函数中的分隔符 组成一个新的字符串 这个功能还是很强大的
列出当前的根
在前面说过 根就是start with开始的地方
START WITH ID =
CONNECT BY PRIOR sjflid = ID;
connect_by_root函数用来列的前面 记录的是当前的根的内容
列出当前是否为叶子
这个比较常见 尤其在动态目录中 在查出的内容是否还有下级时 这个函数是很适用的
START WITH sjflid IS NULL
CONNECT BY sjflid = PRIOR ID;
connect_by_isleaf函数用来判断当前是否包含下级 如果包含的话 说明不是叶子 这里返回 反之 如果不包含下级 这里返回
lishixinzhi/Article/program/Oracle/201311/11193
oracle存储过程中如何调用自定义的函数
updateoracle中调用函数是十分简单的,存储过车调用函数也是一样的。例子如下:
create procedure pro_name1
a显示会话等待的 V$SESSION_ 具体名和含义可以参考Oracle Reference Manual的附录Oracle Wait Eventss
v_para varchar2(200):=‘Im Danny';
begin
--without parameters case
pro_name2;
--with parameters case
pro_DISK 磁盘物理I/Oname3(v_para);
end;
ORACLE字符串处理函数(2)
USERENADD_MONTHS
增加或减去月份
SQL> select to_char(add_months(to_date( yyyymm ) ) yyyymm ) from dual;
TO_CHA
SQL> select to_char(add_months(to_date( yyyymm ) ) yyyymm ) from dual;
TO_CHA
LAST_DAY
返回日期的一天
TO_CHAR(SY TO_CHAR((S
LAST_DAY(S
MONTHS_BEEEN(date date )
给出date date 的月份
SQL> select months_beeen( 月 月 ) mon_beeen from dual;
MON_BEEEN
SQL>selectmonths_beeen(to_date( yyyy mm dd ) to_date( yyyy mm dd )) mon_be from dual;
MON_BE
NEW_TIME(date Sql代码this that )
给出在this时区=other时区的日期和时间
SQL> select to_char(sysdate yyyy mm dd hh :mi:ss ) bj_time to_char(new_time
(sysdate PDT GMT ) yyyy mm dd hh :mi:ss ) los_angles from dual;
BJ_TIME LOS_ANGLES
: : : :
NEXT_DAY(date day )
给出日期date和星期x之后计算下一个星期的日期
SQL> select next_day( 月 星期五 ) next_day from dual;
NEXT_DAY
SYSDATE
用来得到系统的当前日期
SQL> select to_char(sysdate dd mm yyyy day ) from dual;
TO_CHAR(SYSDATE
星期日
SQL> select to_char(trunc(sysdate hh ) yyyy mm dd hh :mi:ss ) hh
to_char(trunc(sysdate mi ) yyyy mm dd hh :mi:ss ) hhmm from dual;
HH HHMM
: : : :
CHARTOROWID
将字符数据类型转换为ROWID类型
SQL> select rowid rowidtochar(rowid) ename from scott emp;
ROWID ROWIDTOCHAR(ROWID) ENAME
AAAAfKAACAAAAEqAAA AAAAfKAACAAAAEqAAA SMITH
AAAAfKAACAAAAEqAAB AAAAfKAACAAAAEqAAB ALLEN
AAAAfKAACAAAAEqAAC AAAAfKAACAAAAEqAAC WARD
AAAAfKAACAAAAEqAAD AAAAfKAACAAAAEqAAD JONES
CONVERT(c dset sset)
将源字符串 sset从一个语言字符集转换到另一个目的dset字符集
conver
strutz
HEXTORAW
将一个十六进制构成的字符串转换为二进制
RAWTOHEXT
将一个二进制构成的字符串转换为十六进制
ROWIDTOCHAR
将ROWID数据类型转换为字符类型
TO_CHAR(date format )
TO_CHAR(SYSDATE YY
/ / : :
TO_DATE(string format )
TO_MULTI_BYTE
将字符串中的单字节字符转化为多字节字符
SQL> select to_multi_byte( 高 ) from dual;
TO
高 TO_NUMBER
将给出的字符转换为数字
SQL> select to_number( ) year from dual;
YEAR
BFILENAME(dir file)
指定一个外部二进制文件
SQL>insert into file_tb values(bfilename( lob_dir image gif ));
CONVERT( x desc source )
将x字段或变量的源source转换为desc
SQL> select sid serial# username decode(mand
none
insert
select
delete
drop
other ) cmd from v$session where type!= background ;
none
none
none
none
none
none
none
none
GAO select
GAO none
DUMP(s fmt start length)
DUMP函数以fmt指定的内部数字格式返回一个VARCHAR 类型的值
SQL> col global_name for a
SQL> col dump_string for a
SQL> set lin
SQL> select global_name dump(global_name ) dump_string from global_name;
GLOBAL_NAME DUMP_STRING
ORACLE WORLD Typ= Len= CharacterSet=ZHS GBK: W O R L D
EMPTY_BLOB()和EMPTY_CLOB()
这两个函数都是用来对大数据类型字段进行初始化作的函数
GREATEST
返回一组表达式中的值 即比较字符的编码大小
SQL> select greatest( AA AB AC ) from dual;
GR
AC
SQL> select greatest( 啊 安 天 ) from dual;
GR
天 LEAST
返回一组表达式中的最小值
SQL> select least( 啊 安 天 ) from dual;
LE
啊 UID
返回标识当前用户的整数
SQL> show user
USER 为 GAO
SQL> select username user_id from dba_users where user_id=uid;
USERNAME USER_ID
GAO
USER
返回当前用户的名字
SQL> select user from dual;
USER
GAO
USEREVN
返回当前用户环境的信息 opt可以是:
ENTRYID SESSIONID TERMINAL ISDBA LABLE LANGUAGE CLIENT_INFO LANG VSIZE
ISDBA 查看当前用户是否是DBA如果是则返回true
SQL> select userenv( isdba ) from dual;
SQL> select userenv( isdba ) from dual;
TRUE
SESSION
返回会话标志
SQL> select userenv( sessionid ) from dual;
USERENV( SESSIONID )
ENTRYID
返回会话人口标志
SQL> select userenv( entryid ) from dual;
USERENV( ENTRYID )
INSTANCE
返回当前INSTANCE的标志
SQL> select userenv( instance ) from dual;
USERENV( INSTANCE )
LANGUAGE
返回当前环境变量
SQL> select userenv( language ) from dual;
USERENV( LANGUAGE )
SIMPLIFIED CHINESE_CHINA ZHS GBK
LANG
SQL> select userenv( lang ) from dual;
USERENV( LANG )
ZHS
TERMINAL
返回用户的终端或机器的标志
SQL> select userenv( terminal ) from dual;
USERENV( TERMINA
GAO
VSIZE(X)
返回X的大小(字节)数
SQL> select vsize(user) user from dual;
VSIZE(USER) USER
SYSTEM
AVG(DISTINCT|ALL)
all表示对所有的值求平均值 distinct只对不同的值求平均值
SQLWKS> create table table (xm varchar( ) sal number( ));
语句已处理
SQLWKS> insert into table values( gao );
SQLWKS> insert into table values( gao );
SQLWKS> insert into table values( zhu );
SQLWKS> mit;
SQL> select g(distinct sal) from gao table ;
AVG(DISTINCTSAL)
SQL> select g(all sal) from gao table ;
AVG(ALLSAL)
MAX(DISTINCT|ALL)
求值 ALL表示对所有的值求值 DISTINCT表示对不同的值求值 相同的只取一次
SQL> select max(distinct sal) from scott emp;
MAX(DISTINCTSAL)
MIN(DISTINCT|ALL)
求最小值 ALL表示对所有的值求最小值 DISTINCT表示对不同的值求最小值 相同的只取一次
SQL> select min(all sal) from gao table ;
MIN(ALLSAL)
STDDEV(distinct|all)
求标准 ALL表示对所有的值求标准 DISTINCT表示只对不同的值求标准
SQL> select stddev(sal) from scott emp;
STDDEV(SAL)
SQL> select stddev(distinct sal) from scott emp;
STDDEV(DISTINCTSAL)
VARIANCE(DISTINCT|ALL)
求协方
SQL> select variance(sal) from scott emp;
VARIANCE(SAL)
GROUP BY
主要用来对一组数进行统计
DEPSELECT CONNECT_BY_ISLEAF flfl TNO COUNT() SUM(SAL)
HAVING
对分组统计再加限制条件
SQL> select deptno count() sum(sal) from scott emp group by deptno hing count()>= ;
DEPTNO COUNT() SUM(SAL)
SQL> select deptno count() sum(sal) from scott emp hing count()>= group by deptno ;
DEPTNO COUNT() SUM(SAL)
ORDER BY
用于对查询到的结果进行排序输出
DEPTNO ENAME SAL
KING
CLARK
MILLER
SCOTT
FORD
JONES
ADAMS
SMITH
BLAKE
ALLEN
TURNER
WARD
MARTIN
lishixinzhi/Article/program/Oracle/201311/16630
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系 836084111@qq.com 删除。