ORACLE的一些问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE的一些问题相关的知识,希望对你有一定的参考价值。
从程序里获取了2个值2016和01, 如何把可以通过一个简单的SQL语句 可以直接统计数据。例如:SELECT COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '01', 0)) "1",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '02', 0)) "2",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '03', 0)) "3",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '04', 0)) "4",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '05', 0)) "5",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '06', 0)) "6",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '07', 0)) "7",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '08', 0)) "8",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '09', 0)) "9",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '10', 0)) "10",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '11', 0)) "11",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '12', 0)) "12",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '13', 0)) "13",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '14', 0)) "14",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '15', 0)) "15",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '16', 0)) "16",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '17', 0)) "17",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '18', 0)) "18",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '19', 0)) "19",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '20', 0)) "20",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '21', 0)) "21",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '22', 0)) "22",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '23', 0)) "23",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '24', 0)) "24",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '25', 0)) "25",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '26', 0)) "26",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '27', 0)) "27",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '28', 0)) "28",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '29', 0)) "29",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '30', 0)) "30",
COUNT(DECODE(TO_CHAR(T1.RECIEVE_DATE, 'DD'), '31', 0)) "31"
FROM
v_sjbb T1 WHERE TO_CHAR(T1.RECIEVE_DATE,'YYYY') = '2016' AND TO_CHAR(T1.RECIEVE_DATE,'MM') = '01' 要如何做到 求教大神来指导
大家好像都理解错我的问题。 我是想问,如何能够通过一个函数或者存储过程 如何调用我这个SQL语句来统计,TO_CHAR(T1.RECIEVE_DATE,'YYYY') = '获取的年份' AND TO_CHAR(T1.RECIEVE_DATE,'MM') = '获取的月份' 类似这样的 然后可以通过一个函数 调用获取(获取的年份,获取的月份)直接统计我上面的SQL语句
从查询看来似乎是要统计v_sjbb中2016年01月中每天的记录个数,并且以一行记录显示出来。
在Oracle 11g开始可以用pivot函数进行行列转换,类似这样:
select *from (select to_char(T1.receive_date, \'DD\') as day_value from v_sjbb T1 where to_char(T1.receive_date, \'YYYY\') = \'2016\' and to_char(T1.receive_date, \'MM\') = \'01\' )
pivot ( count(day_value) as cnt for (day_value) in (1, 2, 3, ..., 31 ) )
下面是pivot的演示,
演示用的SQL:
select *from (
select 1 as day_value from dual
union all
select 2 as day_value from dual
union all
select 2 as day_value from dual
union all
select 3 as day_value from dual
union all
select 4 as day_value from dual)
pivot (count(day_value) as cnt for (day_value) in (1, 2, 3, 4) );追问
in里面超过19 就不显示了 我想要的结果是一个月里31号都要显示,有就显示,没有就为0
追答不会限制in里面的个数,从1写到31即可。模拟测试的结果,
如果你想结果为一行,有31个列的话,你这个写法是正确的。
如果你想结果为31行,有1列显示数量的话,可以使用group by对每天进行分组即可。
SELECT REVIEVE_DATE, COUNT(*)
FROM v_sjbb T1
WHERE TO_CHAR(T1.RECIEVE_DATE,'YYYY') = '2016' AND TO_CHAR(T1.RECIEVE_DATE,'MM') = '01'
GROUP BY REVIEVE_DATE
Windows调试Oracle数据库问题的一些手段
最近需要在Windows的跳板机上访问远程的Oracle数据库进行调试。Windows中只有个精简版Oracle Client,以及PLSQL Developer客户端。
如果用惯了Linux,再用Windows,确实不知所措。但这就是个从生疏到熟练的事儿,最近看的一本书中描述得很恰当,The most effective way to deal with a worry is by acting on it, after all.
在调试过程中,碰到一些问题,记录下。
1. AWR和ASH的获取
通常我们执行awrrpt.sql脚本得到AWR,无论是PLSQL Developer,还是cmd命令行,其实都是可以的。如果是PLSQL Developer,需要在Command Window中操作,
但如果在本地只安装了Oracle Client,没有这个脚本,可以从其他Oracler Server下载一个awrrpt.sql脚本,但是awrrpt.sql中还要调用awrrpti.sql,而且awrrpti.sql还需要调用awrinput.sql和awrinpnm.sql,因此都需要下载。
相应地,获取ASH的脚本ashrpt.sql,会调用ashrpti.sql,这两个都得下载。
2. SQL Profile
当碰到SQL执行计划需要调整,但是应用不能改动代码的时候,SQL Profile是种解决方案。
同样地,Oracle Client不包含SQL Profile的脚本coe_xfr_sql_profile.sql,因此可以从其他地方拷贝一个过来。
cmd到脚本存储路径,sqlplus登录执行@coe_xfr_sql_profile.sql,
3. dbms_stats的显示
PLSQL Developer中的Command窗口执行statistics_level=all,再使用dbmx_xplan.display_cursor,显示为空,
如果改为cmd中执行,就可以正常显示。
4. 10053的trace
有时候我们需要通过10053的trace,看这条SQL选择执行计划的过程,如果在当前会话可以执行SQL,alter session的方式最简单,如果SQL是程序执行的而且带着绑定变量,为了尽量得到执行时的实际情况,还可以通过dbms_sqldiag的dump_trace,不用手工执行SQL,得到一个已经执行并且还在游标缓存中的SQL语句的10053跟踪文件。
P.S. 可参考《有关10053事件,你知道这两个知识点么?》
11g下,DBMS_SQLDIAG包有个存储过程DUMP_TRACE,原理是系统会自动触发一次语句的硬解析以创建跟踪文件。但是,DUMP_TRACE并未写入DBMS_SQLDIAG包的官方文档中,
The procedure will automatically trigger a hard parse of the statement to generate the trace.
Greg Rahn写过一篇文章,并且在$ORACLE_HOME/rdbms/admin/
dbmsdiag.sql有dump_trace的介绍和定义,
$ORACLE_HOME/rdbms/admin/dbmsdiag.sql
-------------------------------- dump_trace ---------------------------------
-- NAME:
-- dump_trace - Dump Optimizer Trace
--
-- DESCRIPTION:
-- This procedure dumps the optimizer or compiler trace for a give SQL
-- statement identified by a SQL ID and an optional child number.
--
-- PARAMETERS:
-- p_sql_id (IN) - identifier of the statement in the cursor
-- cache
-- p_child_number (IN) - child number
-- p_component (IN) - component name
-- Valid values are Optimizer and Compiler
-- The default is Optimizer
-- p_file_id (IN) - file identifier
------------------------------------------------------------------------------
PROCEDURE dump_trace(
p_sql_id IN varchar2,
p_child_number IN number DEFAULT 0,
p_component IN varchar2 DEFAULT 'Optimizer',
p_file_id IN varchar2 DEFAULT null);
从上面介绍的debug级别以及dump_trace定义可知,p_component可以接收SQL_Compiler或者SQL_Optimizer两个事件,p_file_id则和tracefile_identifier相同,表示trace文件标识符,用于快速定位。
测试如下,可以得到sql_id是1mbz30hdgwaz7的第0个子游标对应的SQL执行时的10053跟踪事件文件,文件标识名称TEST,
begin
dbms_sqldiag.dump_trace(p_sql_id=>'1mbz30hdgwaz7', p_child_number=>0, p_component=>'Compiler', p_file_id=>'TEST');
end;
/
使用这种方法,生成的10053跟踪文件,是通过Oracle自动做了一次硬解析,注释部分会增加/* SQL Analyze(xxx) */,
******************************************
----- Current SQL Statement for this session (sql_id=8zrq3v8j6hmzf) -----
/* SQL Analyze(423,0) */ SELECT ...
由于每次存储过程的执行,都会触发一次硬解析操作,因此频繁的执行,对于系统的影响程度,就需要执行者来了解和控制了,算是非常规操作。
5. Oracle Clinet下载
Oracle Client软件下载的路径和归档机制,值得做软件设计的人员学习,他是按照“操作系统平台 -> Oracle Client不同版本 - > Oracle Client不同组件”的维度设置的。
这个链接提供了各个操作平台所有可公开下载的Oracle Client,
https://www.oracle.com/database/technologies/instant-client/downloads.html
以Windows x64为例,这个链接,提供了该平台所有可公开下载的Oracle Client,最新的是21.3.0.0.0,最早的是10.2.0.5,
https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html
在12.2.0.1.0以前,Oracle Client组件拆得很细,无依赖,
12.2.0.1.0开始,就拆成了基础版和扩展版,其中基础版一般包括这两个选择,必须选择其一,
在这个基础上,可以选择扩展,有Tools的,
有Development and Runtime的,
页面还提供了当前最常用的客户端链接快捷方式,目前是19的版本,
Oracle Client-to-Oracle Database version interoperability is detailed in Doc ID 207303.1. For example, applications using Oracle Call Interface 19 can connect to Oracle Database 11.2 or later. Some tools may have other restrictions.
Permanent links to the latest packages are: Basic, Basic Light, SQL*Plus, Tools, SDK, JDBC Supplement , ODBC
这是点击SQL*Plus下载的instantclient-sqlplus-windows.zip,确实相当精简,只能执行sqlplus,但是有时候,这就够用了,
近期更新的文章:
文章分类和索引:
以上是关于ORACLE的一些问题的主要内容,如果未能解决你的问题,请参考以下文章