Number to HH24:MI:SS
Hi,
I have a database field which holds the number of seconds an event has been ongoing. I need to display that in hours, minutes and seconds but have no idea how to do it.
Have looked on the internet for solutions but have found very little.
Thanks for any help
Simon
Using an interval is more robust than relying on the elapsed time being less than 1 day, however, wrapping it with a to_char does give a somewhat unsavory output:
select to_char(NUMTODSINTERVAL(198393,'second')) dts from dual
DTS
+000000002 07:06:33.000000000
1 rows selectedI'm not sure if the to_char function will respect any format models when used with an interval (none of the ones I tried worked), however, you can get around that by formatting it yourself:
with t1 as (select NUMTODSINTERVAL(198393,'second') dts from dual)
select extract(day from dts)|| ' Days, ' ||
extract(hour from dts)|| ' hours ' ||
extract(minute from dts)|| ' minutes and ' ||
extract(second from dts)|| ' seconds' tada
from t1
TADA
2 Days, 7 hours 6 minutes and 33 seconds
1 rows selected
Similar Messages
-
Convert Number to HH24:MI:SS
Hi,
I am using oracle database version 11.2.1 and would like to convert a number in minutes to date format HH24:MI:SS
I am using the following syntax but this does not include seconds, returns format HH24:MI
select FLOOR (165.44 / 60) || ':' || TO_CHAR (MOD (165.44, 60), 'FM00')
from dual
Is it possible to add seconds HH24:MI:SS?select
nInt,
extract(hour from nInt) + extract(day from nInt)*24
||':'||
extract(minute from nInt)
||':'||
round(extract(second from nInt))
as result
from (
select
numtodsinterval(165.44, 'MINUTE')
) nInt
from dual
union all
select
numtodsinterval(165.444, 'MINUTE')
) nInt
from dual
union all
select
numtodsinterval(1540.30, 'MINUTE')
) nInt
from dual
NINT RESULT
+00 02:45:26.400000 "2:45:26"
+00 02:45:26.640000 "2:45:27"
+01 01:40:18.000000 "25:40:18" -
How to come up with a magic number for any table that returns more than 32KB?
I am in a unique situation where in I am trying to retrieve values from multiple tables and publish them as XML output. The problem is based on the condition a few tables could retrieve data more than 32KB and a few less than 32KB. Less than 32KB is not an issue as XML generation is smooth. The minute it reaches greater than 32KB it generates a run time error. Just wondering if there is any way to ensure that the minute the query's results is greater than 32 kb, it should break say - if the results is 35KB, then I should break that result into 32 KB and 3kb; once done then pass this data to be published as an XML output. This is again not just for one table, but all the tables that are called in the function.
Is there any way?? I am unable to get any ideas nor have I done anything so complex from production support stand point. Would appreciate if someone can guide me on this.
The way it is, is as follows:
I have a table called ctn_pub_cntl
CREATE TABLE CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id NUMBER(18)
,table_name VARCHAR2(50)
,last_pub_tms DATE
,queue_name VARCHAR2(50)
,dest_system VARCHAR2(50)
,frequency NUMBER(6)
,status VARCHAR2(8)
,record_create_tms DATE
,create_user_id VARCHAR2(8)
,record_update_tms DATE
,update_user_id VARCHAR2(8)
,CONSTRAINT ctn_pub_cntl_id_pk PRIMARY KEY(ctn_pub_cntl_id)
Data for this is:
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_SBDVSN'
,TO_DATE('10/2/2004 10:17:44PM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.TSZ601.UNP'
,'SAP'
,15
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_TRACK_SGMNT_DN'
,TO_DATE('02/06/2015 9:50:00AM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.WRKORD.UNP'
,'SAP'
,30
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_FXPLA_TRACK_LCTN_DN'
,TO_DATE('10/2/2004 10:17:44PM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.YRDPLN.INPUT'
,'SAP'
,30
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_FXPLA_TRACK_LCTN2_DN'
,TO_DATE('02/06/2015 9:50:00AM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.TSZ601.UNP'
,'SAP'
,120
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_FXPLA_TRACK_LCTN2_DN'
,TO_DATE('04/23/2015 11:50:00PM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.YRDPLN.INPUT'
,'SAP'
,10
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_FIXED_PLANT_ASSET'
,TO_DATE('04/23/2015 11:50:00AM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.WRKORD.UNP'
,'SAP'
,10
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_OPRLMT'
,TO_DATE('03/26/2015 7:50:00AM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.WRKORD.UNP'
,'SAP'
,30
INSERT INTO CTNAPP.ctn_pub_cntl
(ctn_pub_cntl_id
,table_name
,last_pub_tms
,queue_name
,dest_system
,frequency
VALUES
(CTNAPP_SQNC.nextval
,'TRKFCG_OPRLMT_SGMNT_DN'
,TO_DATE('03/28/2015 12:50:00AM','MM/DD/YYYY HH12:MI:SSPM')
,'UT.TSD.WRKORD.UNP'
,'SAP'
,30
COMMIT;
Once the above data is inserted and committed, then I created a function in a package:
CREATE OR REPLACE PACKAGE CTNAPP.CTN_PUB_CNTL_EXTRACT_PUBLISH
IS
TYPE tNameTyp IS TABLE OF ctn_pub_cntl.table_name%TYPE INDEX BY BINARY_INTEGER;
g_tName tNameTyp;
TYPE tClobTyp IS TABLE OF CLOB INDEX BY BINARY_INTEGER;
g_tClob tClobTyp;
FUNCTION GetCtnData(p_nInCtnPubCntlID IN CTN_PUB_CNTL.ctn_pub_cntl_id%TYPE,p_count OUT NUMBER ) RETURN tClobTyp;
END CTNAPP.CTN_PUB_CNTL_EXTRACT_PUBLISH;
--Package body
CREATE OR REPLACE PACKAGE BODY CTNAPP.CTN_PUB_CNTL_EXTRACT_PUBLISH
IS
doc xmldom.DOMDocument;
main_node xmldom.DOMNode;
root_node xmldom.DOMNode;
root_elmt xmldom.DOMElement;
child_node xmldom.DOMNode;
child_elmt xmldom.DOMElement;
leaf_node xmldom.DOMNode;
elmt_value xmldom.DOMText;
tbl_node xmldom.DOMNode;
table_data XMLDOM.DOMDOCUMENTFRAGMENT;
l_ctx DBMS_XMLGEN.CTXHANDLE;
vStrSqlQuery VARCHAR2(32767);
l_clob tClobTyp;
l_xmltype XMLTYPE;
--Local Procedure to build XML header
PROCEDURE BuildCPRHeader IS
BEGIN
child_elmt := xmldom.createElement(doc, 'PUBLISH_HEADER');
child_node := xmldom.appendChild (root_node, xmldom.makeNode (child_elmt));
child_elmt := xmldom.createElement (doc, 'SOURCE_APLCTN_ID');
elmt_value := xmldom.createTextNode (doc, 'CTN');
leaf_node := xmldom.appendChild (child_node, xmldom.makeNode (child_elmt));
leaf_node := xmldom.appendChild (leaf_node, xmldom.makeNode (elmt_value));
child_elmt := xmldom.createElement (doc, 'SOURCE_PRGRM_ID');
elmt_value := xmldom.createTextNode (doc, 'VALUE');
leaf_node := xmldom.appendChild (child_node, xmldom.makeNode (child_elmt));
leaf_node := xmldom.appendChild (leaf_node, xmldom.makeNode (elmt_value));
child_elmt := xmldom.createElement (doc, 'SOURCE_CMPNT_ID');
elmt_value := xmldom.createTextNode (doc, 'VALUE');
leaf_node := xmldom.appendChild (child_node, xmldom.makeNode (child_elmt));
leaf_node := xmldom.appendChild (leaf_node, xmldom.makeNode (elmt_value));
child_elmt := xmldom.createElement (doc, 'PUBLISH_TMS');
elmt_value := xmldom.createTextNode (doc, TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
leaf_node := xmldom.appendChild (child_node, xmldom.makeNode (child_elmt));
leaf_node := xmldom.appendChild (leaf_node, xmldom.makeNode (elmt_value));
END BuildCPRHeader;
--Get table data based on table name
FUNCTION GetCtnData(p_nInCtnPubCntlID IN CTN_PUB_CNTL.ctn_pub_cntl_id%TYPE,p_Count OUT NUMBER) RETURN tClobTyp IS
vTblName ctn_pub_cntl.table_name%TYPE;
vLastPubTms ctn_pub_cntl.last_pub_tms%TYPE;
BEGIN
g_vProcedureName:='GetCtnData';
g_vTableName:='CTN_PUB_CNTL';
SELECT table_name,last_pub_tms
INTO vTblName, vLastPubTms
FROM CTN_PUB_CNTL
WHERE ctn_pub_cntl_id=p_nInCtnPubCntlID;
-- Start the XML Message generation
doc := xmldom.newDOMDocument;
main_node := xmldom.makeNode(doc);
root_elmt := xmldom.createElement(doc, 'PUBLISH');
root_node := xmldom.appendChild(main_node, xmldom.makeNode(root_elmt));
--Append Table Data as Publish Header
BuildCPRHeader;
--Append Table Data as Publish Body
child_elmt := xmldom.createElement(doc, 'PUBLISH_BODY');
leaf_node := xmldom.appendChild (root_node, xmldom.makeNode(child_elmt));
DBMS_SESSION.SET_NLS('NLS_DATE_FORMAT','''YYYY:MM:DD HH24:MI:SS''');
vStrSqlQuery := 'SELECT * FROM ' || vTblName
|| ' WHERE record_update_tms <= TO_DATE(''' || TO_CHAR(vLastPubTms, 'MM/DD/YYYY HH24:MI:SS') || ''', ''MM/DD/YYYY HH24:MI:SS'') ' ;
-- || ' AND rownum < 16'
DBMS_OUTPUT.PUT_LINE(vStrSqlQuery);
l_ctx := DBMS_XMLGEN.NEWCONTEXT(vStrSqlQuery);
DBMS_XMLGEN.SETNULLHANDLING(l_ctx, 0);
DBMS_XMLGEN.SETROWSETTAG(l_ctx, vTblName);
-- Append Table Data as XML Fragment
l_clob(1):=DBMS_XMLGEN.GETXML(l_ctx);
elmt_value := xmldom.createTextNode (doc, l_clob(1));
leaf_node := xmldom.appendChild (leaf_node, xmldom.makeNode (elmt_value));
xmldom.writeToBuffer (doc, l_clob(1));
l_clob(1):=REPLACE(l_clob(1),'<?xml version="1.0"?>', NULL);
l_clob(1):=REPLACE(l_clob(1),'<', '<');
l_clob(1):=REPLACE(l_clob(1),'>', '>');
RETURN l_clob;
DBMS_OUTPUT.put_line('Answer is' ||l_clob(1));
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('There is no data with' || SQLERRM);
g_vProcedureName:='GetCtnData';
g_vTableName:='CTN_PUB_CNTL';
g_vErrorMessage:=SQLERRM|| g_vErrorMessage;
g_nSqlCd:=SQLCODE;
ctn_log_error('ERROR',g_vErrorMessage,'SELECT',g_nSqlCd,p_nInCtnPubCntlID,g_vPackageName,g_vProcedureName,g_vTableName);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR : ' || SQLERRM);
ctn_log_error('ERROR',g_vErrorMessage,'OTHERS',g_nSqlCd,p_nInCtnPubCntlID,g_vPackageName,g_vProcedureName,g_vTableName);
END GetCtnData;
PROCEDURE printClob (result IN OUT NOCOPY CLOB) IS
xmlstr VARCHAR2 (32767);
line VARCHAR2 (2000);
BEGIN
xmlstr := DBMS_LOB.SUBSTR (result, 32767);
LOOP
EXIT WHEN xmlstr IS NULL;
line := SUBSTR (xmlstr, 1, INSTR (xmlstr, CHR (10)) - 1);
DBMS_OUTPUT.put_line (line);
xmlstr := SUBSTR (xmlstr, INSTR (xmlstr, CHR (10)) + 1);
END LOOP;
END printClob;
END CTN_PUB_CNTL_EXTRACT_PUBLISH;
If you notice my query:
vStrSqlQuery := 'SELECT * FROM ' || vTblName
|| ' WHERE record_update_tms <= TO_DATE(''' || TO_CHAR(vLastPubTms, 'MM/DD/YYYY HH24:MI:SS') || ''', ''MM/DD/YYYY HH24:MI:SS'') ' ;
|| ' AND rownum < 16'
The minute I comment
|| ' AND rownum < 16' ;
, it throws an error because this query returns around 600 rows and all of those rows need to be published as XML and the tragedy is that there is a C program in between as well i.e. C will call my packged functions and then will do all the processing. Once this is done will pass the results back to C program. So obviously C does not recognise CLOB and somewhere in the process I have to convert the CLOB to VARCHAR or instead of CLOB I have to use VARCHAR array as a return type. This is my challenge.
Anyone that can help me to find out the required magic number and also a brief know how, I would appreciate that. Many thanks in advance.Not sure I understand which part is failing.
Is it the C program calling your packaged function? Or does the error occur in the PL/SQL code, in which case you should be able to pinpoint where it's wrong?
A few comments :
1) Using DOM to build XML out of relational data? What for? Use SQL/XML functions.
2) Giving sample data is usually great, but it's not useful here since we can't run your code. We're missing the base tables.
3) This is wrong :
vStrSqlQuery := 'SELECT * FROM ' || vTblName || ' WHERE record_update_tms <= TO_DATE(''' || TO_CHAR(vLastPubTms, 'MM/DD/YYYY HH24:MI:SS') || ''', ''MM/DD/YYYY HH24:MI:SS'') ' ;
A bind variable should be used here for the date.
4) This is wrong :
elmt_value := xmldom.createTextNode (doc, l_clob(1));
createTextNode does not support CLOB so it will fail as soon as the CLOB you're trying to pass exceeds 32k.
Maybe that's the problem you're referring to?
5) This is most wrong :
l_clob(1):=REPLACE(l_clob(1),'<?xml version="1.0"?>', NULL);
l_clob(1):=REPLACE(l_clob(1),'<', '<');
l_clob(1):=REPLACE(l_clob(1),'>', '>');
I understand what you're trying to do but it's not the correct way.
You're trying to convert a text() node representing XML in escaped form back to XML content.
The problem is that there are other things to take care of besides just '<' and '>'.
If you want to insert an XML node into an existing document, treat that as an XML node, not as a string.
Anyway,
Anyone that can help me to find out the required magic number
That would be a bad idea. Fix what needs to be fixed.
And please clearly state which part is failing : the C program or the PL/SQL code?
I'd vote for PL/SQL, as pointed out in [4]. -
Function to convert string to number
Hi there,
I wrote a function which converted a hor minute component of a date to a number. Now I need to do the same with a string (because the hours could be more then 23:95). Anyway here is my function. How can I rewrite it so it will accept a string as in parameter. Somwhow I can not work it out. Thanks a lot.
Chris
function calculate_hours_project(in_hours in DATE)
RETURN number
AS
hrs CHAR(2);
mins CHAR(2);
BEGIN
hrs := to_char(in_day, 'HH24');
mins := to_char(in_day, 'MI');
if hrs is not null and mins is not null then
RETURN to_number(hrs + (mins/60));
else
RETURN 0;
end if;
END calculate_hours_project;Wouldn't it just be something like this?
sql>create or replace function calculate_hours_project(in_hours in varchar2)
2 return number
3 is
4 begin
5 return to_number(substr(in_hours, 1, instr(in_hours, ':') - 1)) +
6 to_number(substr(in_hours, instr(in_hours, ':') + 1) / 60);
7 end calculate_hours_project;
8 /
Function created.
sql>select calculate_hours_project('08:05') from dual;
CALCULATE_HOURS_PROJECT('08:05')
8.0833333
1 row selected.
sql>select calculate_hours_project('35:34') from dual;
CALCULATE_HOURS_PROJECT('35:34')
35.566667
1 row selected. -
How can I determine what is the minimum SCN number I need to restore up to.
Say if I have a full database backup, I know I have file inconsistency, but I want to know what is the minimum time or SCN number a need to roll forward to in order to be able to open the database?
For example: I do a database restore.
restore database ;
RMAN> sql 'alter database open read only';
sql statement: alter database open read only
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03009: failure of sql command on default channel at 03/16/2009 15:00:04
RMAN-11003: failure during parse/execution of SQL statement: alter database open read only
ORA-16004: backup database requires recovery
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/u01/oradata/p1/system01.dbf'
I need need to apply archive log files. All references I find for ORA-00194 state the solution is to "apply more logs until the file is consistent " But "HOW MANY LOGS", or more apporaite up to what time or SCN? How does one determine what TIME or SCN is required to get all file consistent?
I thought this query might provide the answer, but it doesn't
select max(checkpoint_change#)
from v$datafile_header
MAX(CHECKPOINT_CHANGE#)
7985876903
--It applies a bit more redo, but not enough to make my datafiles consistent.
recover database until SCN=7985876903 ;
Starting recover at 03/16/09 15:04:54
using channel ORA_DISK_1
using channel ORA_DISK_2
using channel ORA_DISK_3
using channel ORA_DISK_4
using channel ORA_DISK_5
using channel ORA_DISK_6
using channel ORA_DISK_7
using channel ORA_DISK_8
starting media recovery
channel ORA_DISK_1: starting archive log restore to default destination
channel ORA_DISK_1: restoring archive log
archive log thread=1 sequence=18436
channel ORA_DISK_1: reading from backup piece /temp-oracle/backup/hot/p1/20090315/hourly.arch_P1_47353_681538638_1
channel ORA_DISK_1: restored backup piece 1
piece handle=/temp-oracle/backup/hot/p1/20090315/hourly.arch_P1_47353_681538638_1 tag=TAG20090315T041716
channel ORA_DISK_1: restore complete, elapsed time: 00:02:26
archive log filename=/u01/app/oracle/flash_recovery_area/P1/archivelog/2009_03_16/o1_mf_1_18436_4vxd81yc_.arc thread=1 se quence=18436
Oracle Error:
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/u01/oradata/p1/system01.dbf'
I've discover I need to apply archive logs until this query reports all datafiles as FUZZY=NO , but this only works by guessing at some time periord to roll forward to, then checking the FUZZY column, and try again. Is there a way to know, I have to roll forward to a specific SNC in order for all my datafiles to be consistent?
select file#
, status
, checkpoint_change#
, checkpoint_time
, FUZZY
, RECOVER
,LAST_DEALLOC_SCN
from v$datafile_header
order by checkpoint_time
Thanks,
JasonThe minimum point in time is the time when the last backup piece for datafiles in that backup was completed.
Your alert.log should show the redo log sequence number at that time.
You can query V$ARCHIVED_LOG and get the FIRST_CHANGE# of the first archivedlog generated after that backup piece completed.
A
LIST BACKUP;in RMAN should also show you the SCNs at the time of the backups.
You can also query SCN_TO_TIMESTAMP -- eg
select timestamp_to_scn(to_timestamp('15-MAR-09 09:24:01','DD-MON-RR HH24:MI:SS')) from dual;will return an approximation of the SCN.
Hemant K Chitale
http://hemantoracledba.blogspot.com
Edited by: Hemant K Chitale on Mar 17, 2009 9:41 AM
added the LIST BACKUP command from RMAN. -
how can I find the number of concurrent users in oracle 10g;
thank youYou mean ACTIVE users ??
Use following script :
active.sql
set pagesize 120
set linesize 150
select username, count(*) from v$session where status = 'ACTIVE'
group by username;
column spid format a5
column sid format 9999
column serial# format 999999
column username format A9
column schemaname format A8
column osuser format a20
column machine format a15
column logondate format a15
column terminal format a10
column status format a10
column module format a25
select a.sid, a.serial#, b.spid,
--a.process,
a.username,
to_char(a.logon_time,'DD-MM HH24:MI:SS') LogonDate, a.osuser, a.machine, a.status, a.module
from v$session a, v$process b where a.paddr = b.addr
and a.status = 'ACTIVE' and a.username is not null
order by 9;
--order by b.spid; -
How to get the number of minutes or hours from date arithmetic ?
Thanks in advance,
I have two date fields that I would like to derive the number of minutes or hours via the following:
select start_date - end_date from dual;
How do I get HH:MM results ? ThanksIf greater than 24 hours you'll need to calculate the hours and minutes as numbers individually. (You can then display them in whatever format you choose)
SQL> ed
Wrote file afiedt.buf
1 with t as (select to_date('6-10-2008 08:00','DD-MM-YYYY HH24:MI') as from_dt, to_date('7-10-2008 12:30','DD-MM-YYYY HH24:MI') as to_dt from dual)
2 --
3 select from_dt, to_dt, to_dt-from_dt
4 ,to_char(trunc(sysdate)+(to_dt-from_dt),'HH24:MI') as hrs_mins
5 ,trunc((to_dt-from_dt)*24) as hrs
6 ,trunc((((to_dt-from_dt)*24)-trunc((to_dt-from_dt)*24))*60) as mins
7* from t
SQL> /
FROM_DT TO_DT TO_DT-FROM_DT HRS_M HRS MINS
06-OCT-2008 08:00 07-OCT-2008 12:30 1.1875 04:30 28 30
SQL> -
Conversion from date to number & display a date in a textfield
I Have 2 issues
The first one:
I need to extract the hour from a date variable.
This is the code I already have:
NUM_TOT := NUM_TEL + to_number('PROGRAMMINGS1.PRG_START','hh24');
NUM_TOT & NUM_TEL are number variables,
PROGRAMMINGS1.PRG_START is a Textfiel with a dateformat. There can only be an houre like 24:59:00 entered.
So in this example I just want the houre and convert it to a number.
The second:
I want to make a date from a few numbers & then display it in a texfield.
This is the code I already have:
VAR_DATE := NUM_TEL || ':' || NUM_LENGTH || ':00';
:PROGRAMMINGS.PRG_END := to_date(VAR_DATE,'hh24:mi:ss');
Between the 2 lines of code i places a message(VAR_DATE) for testing.
When the program display VAR_DATE then i can see the good date at the bottom of the screen.
But when I place my variable in the textfield it looks like: 00:00:00. What am I doing wrong?
Who can help me.
With regards
StefanieVerdi wrote:
Problem: During the conversion (both implicit and explicit conversion with a format mask) I lose the "00" hours and "00" minutes and receive something like this: "10-JAN-13 *12*.00.00.000000000 AM".I don't think you are necessarily losing any information whatsoever. It's probably more of a function of your NLS_TIMESTAMP_FORMAT and NLS_DATE_FORMAT. For example your NLS_DATE_FORMAT could be setup by default for a HH24 (24 hour time) which would report midnight as "00" hours. However, it looks like your NLS_TIMESTAMP_FORMAT is setup with a "HH" format with a meridian indicator which means 12 hours time.
Your comparisons should be using date/timestamp data types anyways so as long as the input value is converted properly into a date type this shouldn't matter anyways.
You can see what is actually stored by using the DUMP function:
SQL> SELECT DUMP(TO_TIMESTAMP(TO_CHAR(TRUNC(SYSDATE,'DD'),'MM/DD/YYYY HH:MI:SS AM'))) AS TSTAMP
2 , DUMP(TRUNC(SYSDATE,'DD')) AS DT
3 FROM DUAL
4 /
TSTAMP DT
Typ=187 Len=20: 218,7,1,13,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0 Typ=13 Len=8: 218,7,1,13,0,0,0,0As you can see the TSTAMP and DT store nearly the same values (218,7,1,13), but the TSTAMP has more precision because of fractional seconds.
HTH!
Edited by: Centinul on Jan 13, 2010 7:23 AM -
Check which table has no column with specific name over number of tables
Hello,
Withing my schema I have 66 tables, all of them have column last_update_date. Though not all have the column program_update_date. The problem is I want to go through all the tables and know which tables does not have the program_update_date column. It is to be noted that if the table does not have the program_update_date column query 2 will be used instead of query 1.
query1:
select last_extract_date,
to_char(min(greatest(nvl(*last_update_date*,'01-Jan-10'),nvl(*program_update_date*,'01-Jan-10'))),'DD-MON-YY HH24:MI:SS') mi,
to_char(max(greatest(nvl(*last_update_date*,'01-Jan-10'),nvl(*program_update_date*,'01-Jan-10'))),'DD-MON-YY HH24:MI:SS') ma
from table_names
group by last_extract_date
order by last_extract_date desc;
query2:
select last_extract_date,
to_char(min(nvl(last_update_date,'01-Jan-10')),'DD-MON-YY HH24:MI:SS') mi,
to_char(max(nvl(last_update_date,'01-Jan-10')),'DD-MON-YY HH24:MI:SS') ma
from mispa_events
group by last_extract_date
order by last_extract_date desc ;
Please find the PLSQL code that should be used:
Declare
cursor C_1 is
select unique table_name from user_tables; table_names varchar2(240); Begin Open C_1; Loop Fetch C_1 into table_names; EXIT WHEN C_1%NOTFOUND;
EXECUTE IMMEDIATE('select last_extract_date,
to_char(min(greatest(nvl(last_update_date,''01-Jan-10''),nvl(program_update_date,''01-Jan-10''))),''DD-MON-YY HH24:MI:SS'') mi,
to_char(max(greatest(nvl(last_update_date,''01-Jan-10''),nvl(program_update_date,''01-Jan-10''))),''DD-MON-YY HH24:MI:SS'') ma
from ' || table_names ||'
group by last_extract_date
order by last_extract_date desc');
End Loop;
Close C_1;
COMMIT;
End;
Please help.
Thanks in advance.
Edited by: P.Sam on Jun 14, 2010 5:00 PMwhy not use user_tab_columns
SQL> desc user_tab_columns
Name Null? Type
TABLE_NAME NOT NULL VARCHAR2(30)
COLUMN_NAME NOT NULL VARCHAR2(30)
DATA_TYPE VARCHAR2(106)
DATA_TYPE_MOD VARCHAR2(3)
DATA_TYPE_OWNER VARCHAR2(30)
DATA_LENGTH NOT NULL NUMBER
DATA_PRECISION NUMBER
DATA_SCALE NUMBER
NULLABLE VARCHAR2(1)
COLUMN_ID NUMBER
DEFAULT_LENGTH NUMBER
DATA_DEFAULT LONG
NUM_DISTINCT NUMBER
LOW_VALUE RAW(32)
HIGH_VALUE RAW(32)
DENSITY NUMBER
NUM_NULLS NUMBER
NUM_BUCKETS NUMBER
LAST_ANALYZED DATE
SAMPLE_SIZE NUMBER
CHARACTER_SET_NAME VARCHAR2(44)
CHAR_COL_DECL_LENGTH NUMBER
GLOBAL_STATS VARCHAR2(3)
USER_STATS VARCHAR2(3)
AVG_COL_LEN NUMBER
CHAR_LENGTH NUMBER
CHAR_USED VARCHAR2(1)
V80_FMT_IMAGE VARCHAR2(3)
DATA_UPGRADED VARCHAR2(3)
HISTOGRAM VARCHAR2(15) -
Wrong number or types of argumnet in a call to error
Hi all,
Below is my stored proc and it has a input parameter 'c_count_or_perc' . I have passed value to this parameter as in the if block.
But I got the error as "wrong number or types of argumnet in a call to ' .
I really dont know how to pass input value to this parameter .
Could anyone please help?
{code}
PROCEDURE edr_rpt_gen_error_by_hour
in_report_parameter_id IN report_tasks.report_task_id%TYPE,
c_count_or_perc IN VARCHAR2 ,
report_data OUT SYS_REFCURSOR,
chart_data OUT SYS_REFCURSOR,
footer_data OUT SYS_REFCURSOR
{code}
In below 'IF THEN ELSE' block , ( based on the <condition> ) , I dont know how to pass value to input parameter c_count_or_perc .
{code}
IF (c_count_or_perc = 'ERROR BY HOUR') THEN
my_error_text := get_row_error_text;
my_total_text := get_row_total_text;
ELSE
my_error_text := get_row_error_text;
my_total_text := '';
DELETE edr_report_by_hour_output
WHERE row_type = 'Summary Row'
AND row_type = 'Final Row';
END IF;
{code}
Here I have pasted the full package. Could please tell me , what are ways tht I could pass value to the given input parameter.
{code}
CREATE OR REPLACE PACKAGE edr_rpt_error_by_hour_package AS
PROCEDURE edr_rpt_gen_error_by_hour
in_report_parameter_id IN report_tasks.report_task_id%TYPE,
c_count_or_perc IN VARCHAR2 ,
report_data OUT SYS_REFCURSOR,
chart_data OUT SYS_REFCURSOR,
footer_data OUT SYS_REFCURSOR
FUNCTION error_data
in_lane_id edr_report_by_hour_output.lane_id%TYPE,
in_direction_id edr_report_by_hour_output.direction_id%TYPE,
in_interval_start_date_time edr_report_by_hour_output.interval_start_date_time%TYPE,
in_interval_end_date_time edr_report_by_hour_output.interval_end_date_time%TYPE,
in_hour_start edr_report_by_hour_output.hour_start%TYPE,
in_hour_end edr_report_by_hour_output.hour_end%TYPE,
in_min_error NUMBER,
in_max_error NUMBER
RETURN NUMBER;
END edr_rpt_error_by_hour_package;
CREATE OR REPLACE PACKAGE BODY edr_rpt_error_by_hour_package AS
FUNCTION error_data
in_lane_id edr_report_by_hour_output.lane_id%TYPE,
in_direction_id edr_report_by_hour_output.direction_id%TYPE,
in_interval_start_date_time edr_report_by_hour_output.interval_start_date_time%TYPE,
in_interval_end_date_time edr_report_by_hour_output.interval_end_date_time%TYPE,
in_hour_start edr_report_by_hour_output.hour_start%TYPE,
in_hour_end edr_report_by_hour_output.hour_end%TYPE,
in_min_error NUMBER,
in_max_error NUMBER
RETURN NUMBER
IS
my_count_result NUMBER(18);
BEGIN
SELECT NVL(SUM(error_count), 0 )
INTO my_count_result
FROM
SELECT site_lane_id
FROM edr_rpt_tmp_report_lanes
WHERE edr_rpt_tmp_report_lanes.output_lane_id = in_lane_id
AND edr_rpt_tmp_report_lanes.output_direction_id = in_direction_id
) report_lanes
JOIN edr_error_by_hour_report_data
ON edr_error_by_hour_report_data.site_lane_id = report_lanes.site_lane_id
AND edr_error_by_hour_report_data.bin_start_date_time >= in_interval_start_date_time
AND edr_error_by_hour_report_data.bin_start_date_time < in_interval_end_date_time
AND edr_error_by_hour_report_data.hour >= in_hour_start
AND edr_error_by_hour_report_data.hour < in_hour_end
AND edr_error_by_hour_report_data.error_code >= in_min_error
AND edr_error_by_hour_report_data.error_code <= in_max_error
return my_count_result;
END error_data;
FUNCTION get_row_error_text
RETURN VARCHAR2
IS
my_row_error_text VARCHAR2(10000);
my_row_error_entry VARCHAR2(10000);
CURSOR row_error_text IS
SELECT 'edr_rpt_error_by_hour_package.error_data('
||'lane_id, '
||'direction_id, '
||'interval_start_date_time, '
||'interval_end_date_time, '
||'hour_start, '
||'hour_end, '
|| error_code || ', '
|| error_code || ') "'|| error_message.error_short_message || '"'
FROM error_message
WHERE error_code >= 0 and error_code < 19
ORDER BY error_code;
BEGIN
my_row_error_text := '';
my_row_error_entry := '';
-- generate the error code function calls
OPEN row_error_text;
LOOP
FETCH row_error_text INTO my_row_error_entry;
EXIT WHEN row_error_text%NOTFOUND;
my_row_error_text := my_row_error_text || ', ' || my_row_error_entry;
END LOOP;
CLOSE row_error_text;
RETURN my_row_error_text;
END get_row_error_text;
FUNCTION get_row_total_text
RETURN VARCHAR2
IS
my_row_error_text VARCHAR2(10000);
BEGIN
my_row_error_text := '';
-- generate the 'total' column function call
SELECT 'edr_rpt_error_by_hour_package.error_data('
||'lane_id, '
||'direction_id, '
||'interval_start_date_time, '
||'interval_end_date_time, '
||'hour_start, '
||'hour_end, '
|| MIN(error_code) || ', '
|| MAX(error_code) || ') "Total"'
INTO my_row_error_text
FROM error_message
WHERE error_code >= 0 and error_code < 19;
RETURN (', ' || my_row_error_text);
END get_row_total_text;
FUNCTION get_error_data_pct
in_lane_id edr_report_by_hour_output.lane_id%TYPE,
in_direction_id edr_report_by_hour_output.direction_id%TYPE,
in_interval_start_date_time edr_report_by_hour_output.interval_start_date_time%TYPE,
in_interval_end_date_time edr_report_by_hour_output.interval_end_date_time%TYPE,
in_hour_start edr_report_by_hour_output.hour_start%TYPE,
in_hour_end edr_report_by_hour_output.hour_end%TYPE,
in_min_error NUMBER,
in_max_error NUMBER
RETURN NUMBER
IS
my_count NUMBER(18);
my_total NUMBER(18);
my_count_pct NUMBER(18);
my_count_result NUMBER(18);
BEGIN
my_count_pct := 0 ;
my_count_result := error_data (
in_lane_id,
in_direction_id,
in_interval_start_date_time,
in_interval_end_date_time,
in_hour_start,
in_hour_end,
in_min_error,
in_max_error
IF (my_count_result > 0 ) THEN
my_total := error_data (
in_lane_id,
in_direction_id,
in_interval_start_date_time,
in_interval_end_date_time,
in_hour_start,
in_hour_end,
1,
19
my_count_pct := ROUND((my_count_result / my_total) * 100 ,2);
END IF;
return my_count_pct;
END get_error_data_pct;
PROCEDURE edr_error_by_hour_use_per_veh
in_report_parameter_id IN report_tasks.report_task_id%TYPE
IS
BEGIN
DELETE FROM edr_error_by_hour_report_data;
INSERT INTO edr_error_by_hour_report_data
site_id,
site_lane_id,
bin_start_date_time,
hour,
error_code,
error_count
SELECT
site_id,
site_lane_id,
bin_start_date_time,
hour,
error_code,
COUNT(1)
FROM (SELECT site_id,
site_lane_id,
( SELECT NVL(MAX(interval_start_date_time), date_time)
FROM edr_rpt_tmp_grouping_table
WHERE interval_start_date_time <= date_time) bin_start_date_time,
TO_NUMBER(TO_CHAR(date_time, 'hh24')) hour,
NVL(traffic_error.error_code, 0) error_code
FROM edr_error_by_hour_veh_data
LEFT OUTER JOIN traffic_error
ON traffic_error.record_id = edr_error_by_hour_veh_data.record_id
) vehicles
GROUP BY
site_id,
site_lane_id,
bin_start_date_time,
hour,
error_code;
END edr_error_by_hour_use_per_veh;
PROCEDURE edr_error_by_hour_data_type
in_report_parameter_id IN report_tasks.report_task_id%TYPE,
in_data_type IN VARCHAR2,
out_data_type_used OUT VARCHAR2
IS
my_bin_entry_count NUMBER(12,0);
my_veh_entry_count NUMBER(12,0);
BEGIN
IF(UPPER(in_data_type) = 'BINNED') THEN
-- Error information can only be read from Per Vehicle data records
-- - using bins-only is not a supported option
RAISE_APPLICATION_ERROR(-20101,'Binned data cannot be used for this report.');
ELSIF (UPPER(in_data_type) = 'PERVEHICLE')
OR (UPPER(in_data_type) = 'COMBINED')
THEN
out_data_type_used := 'Per Vehicle (All Vehicles)';
edr_error_by_hour_use_per_veh( in_report_parameter_id );
ELSE
RAISE_APPLICATION_ERROR(-20101, 'The data type specified is not recognized.');
END IF;
END edr_error_by_hour_data_type;
PROCEDURE edr_error_by_hour_get_veh_data
in_report_parameter_id IN NUMBER,
in_site_id IN NUMBER,
in_start_date_time IN TIMESTAMP,
in_end_date_time IN TIMESTAMP,
in_report_level_min IN NUMBER,
in_report_level_max IN NUMBER
IS
BEGIN
--Clear the edr_error_by_hour_veh_data temporary table and populate it with the data for the requested
--report.
DELETE FROM edr_error_by_hour_veh_data;
INSERT INTO edr_error_by_hour_veh_data
site_id,
site_lane_id,
record_id,
date_time,
vehicle_error_count,
vehicle_status
SELECT site_to_data_source_lane_v.site_id,
site_to_data_source_lane_v.site_lane_id,
traffic_record.record_id,
traffic_record.datetime,
NVL((SELECT COUNT(1)
FROM traffic_error
WHERE traffic_error.record_id = traffic_record.record_id), 0) vehicle_error_count,
NVL((SELECT SUM(status_code)
FROM traffic_status
WHERE traffic_status.record_id = traffic_record.record_id), 0) vehicle_status
FROM traffic_record
LEFT OUTER JOIN traffic_class
ON traffic_record.record_id = traffic_class.record_id
JOIN site_to_data_source_lane_v
ON traffic_record.data_source_id = site_to_data_source_lane_v.data_source_id
AND traffic_record.lane = site_to_data_source_lane_v.data_source_lane_id
JOIN edr_rpt_tmp_report_lanes
ON site_to_data_source_lane_v.site_lane_id = edr_rpt_tmp_report_lanes.site_lane_id
JOIN edr_rpt_tmp_report_classes
ON NVL(traffic_class.v_class, 0) = edr_rpt_tmp_report_classes.class_id
JOIN edr_rpt_tmp_inclusion_table
ON TRUNC(traffic_record.datetime) = TRUNC(edr_rpt_tmp_inclusion_table.date_time)
WHERE site_to_data_source_lane_v.site_id = in_site_id
AND traffic_record.datetime >= in_start_date_time
AND traffic_record.datetime < in_end_date_time
AND traffic_class.class_level >= in_report_level_min
AND traffic_class.class_level <= in_report_level_max;
END edr_error_by_hour_get_veh_data;
PROCEDURE edr_rpt_gen_error_by_hour
in_report_parameter_id IN report_tasks.report_task_id%TYPE,
c_count_or_perc IN VARCHAR2 ,
report_data OUT SYS_REFCURSOR,
chart_data OUT SYS_REFCURSOR,
footer_data OUT SYS_REFCURSOR
AS
my_date_format_mask VARCHAR2(50);
my_start_date_time TIMESTAMP;
my_end_date_time TIMESTAMP;
my_lane_grouping VARCHAR2(10);
my_interval_duration NUMBER(2);
my_site_id sites.site_id%TYPE;
my_selected_data_type VARCHAR2(50);
my_used_data_type VARCHAR2(50);
my_report_data_statement VARCHAR2(25000);
my_chart_data_statement VARCHAR2(25000);
my_good_weight_viol_total NUMBER(12,0);
my_data_type_used VARCHAR2(50);
my_per_vehicle_total NUMBER(12,0);
my_binned_vehicle_total NUMBER(12,0);
my_error_vehicle_total NUMBER(12,0);
my_status_vehicle_total NUMBER(12,0);
my_good_weight_total NUMBER(12,0);
my_status_clear_total NUMBER(12,0);
my_good_weight_statuses_mask NUMBER(12,0);
my_error_text VARCHAR2(25000);
my_total_text VARCHAR2(25000);
my_error_row_pct_report VARCHAR2(25);
BEGIN
my_date_format_mask := edr_rpt_generic_package.edr_rpt_get_date_format_mask(in_report_parameter_id);
my_start_date_time := edr_rpt_generic_package.edr_rpt_get_start_date_time(in_report_parameter_id, my_date_format_mask);
my_end_date_time := edr_rpt_generic_package.edr_rpt_get_end_date_time(in_report_parameter_id, my_date_format_mask);
my_lane_grouping := edr_rpt_generic_package.edr_rpt_get_lane_grouping(in_report_parameter_id);
my_site_id := edr_rpt_generic_package.edr_rpt_get_site_id(in_report_parameter_id);
my_selected_data_type := edr_rpt_generic_package.edr_rpt_get_data_type(in_report_parameter_id);
-- ensure selected classes and lanes temp tables have been populated
edr_rpt_generic_package.edr_rpt_gen_tmp_lanes(in_report_parameter_id);
edr_rpt_generic_package.edr_rpt_gen_tmp_classes(in_report_parameter_id);
my_good_weight_statuses_mask := edr_rpt_generic_package.get_good_weight_status_mask(in_report_parameter_id);
edr_rpt_generic_package.edr_rpt_gen_inclusion_table(
in_report_parameter_id,
my_date_format_mask,
my_start_date_time,
my_end_date_time
edr_rpt_generic_package.edr_rpt_gen_grouping_table(
in_report_parameter_id,
my_date_format_mask,
my_start_date_time,
my_end_date_time
edr_rpt_generic_package.gen_rpt_by_hour_output_table
in_report_parameter_id
edr_rpt_error_by_hour_package.edr_error_by_hour_get_veh_data
in_report_parameter_id,
my_site_id,
my_start_date_time,
my_end_date_time,
0, --Hardcoded until reclassification is supported.
0 --Hardcoded until reclassification is supported.
edr_rpt_error_by_hour_package.edr_error_by_hour_data_type
in_report_parameter_id,
my_selected_data_type,
my_used_data_type
IF (c_count_or_perc = 'ERROR BY HOUR') THEN
my_error_text := get_row_error_text;
my_total_text := get_row_total_text;
ELSE
my_error_text := get_row_error_text;
my_total_text := '';
DELETE edr_report_by_hour_output
WHERE row_type = 'Summary Row'
AND row_type = 'Final Row';
END IF;
COMMIT;
my_report_data_statement :=
'SELECT rank "Rank", '
|| ' ROW_TYPE "Row Type", '
|| ' interval_start_date_time "Date", '
|| ' interval_start_date_time, '
|| ' hour_label "Chart X-Axis", '
|| ' lane_id "Group Id" , '
|| ' ''None'' "Group Name", '
|| ' hour_label "Hour" '
|| my_error_text
|| my_total_text
|| ' FROM edr_report_by_hour_output '
|| ' ORDER BY lane_id, '
|| ' direction_id, '
|| ' interval_start_date_time, '
|| ' hour_end, '
|| ' rank, '
|| ' hour_start'
dbms_output.put_line('SQL start------------------------');
dbms_output.put_line(my_report_data_statement);
dbms_output.put_line('SQL end--------------------------');
my_chart_data_statement :=
' SELECT hour_start "X Axis", '
|| ' lane_id "Group" '
|| edr_rpt_error_by_hour_package.get_row_error_text
|| ' FROM '
|| ' ( '
|| ' SELECT lane_id, '
|| ' direction_id, '
|| ' hour_start, '
|| ' hour_end, '
|| ' min(interval_start_date_time) interval_start_date_time, '
|| ' max(interval_end_date_time) interval_end_date_time '
|| ' FROM edr_report_by_hour_output '
|| ' WHERE hour_end = hour_start + 1 '
|| ' GROUP BY lane_id, direction_id, hour_start, hour_end '
|| ' ) '
|| ' order by "Group", hour_start '
dbms_output.put_line('SQL start------------------------');
dbms_output.put_line(my_chart_data_statement);
dbms_output.put_line('SQL end--------------------------');
SELECT my_used_data_type
INTO my_data_type_used
FROM SYS.DUAL;
SELECT NVL(COUNT(record_id), 0)
INTO my_per_vehicle_total
FROM edr_error_by_hour_veh_data;
SELECT NVL(COUNT(record_id), 0)
INTO my_status_vehicle_total
FROM edr_error_by_hour_veh_data
WHERE vehicle_status > 0
AND vehicle_error_count = 0;
SELECT NVL(COUNT(record_id), 0)
INTO my_error_vehicle_total
FROM edr_error_by_hour_veh_data
WHERE vehicle_error_count > 0;
SELECT NVL(COUNT(record_id), 0)
INTO my_status_clear_total
FROM edr_error_by_hour_veh_data
WHERE vehicle_status = 0
AND vehicle_error_count = 0;
SELECT NVL(SUM(error_count), 0)
INTO my_binned_vehicle_total
FROM edr_error_by_hour_report_data;
SELECT NVL(COUNT(DISTINCT edr_error_by_hour_veh_data.record_id), 0)
INTO my_good_weight_total
FROM edr_error_by_hour_veh_data
WHERE vehicle_error_count = 0
AND BITAND(vehicle_status, my_good_weight_statuses_mask) = 0;
-- insert vehicle totals into the temporary table
DELETE FROM edr_rpt_tmp_veh_totals_table;
INSERT INTO edr_rpt_tmp_veh_totals_table
data_type_used,
per_vehicle_total,
binned_vehicle_total,
error_vehicle_total,
status_vehicle_total,
good_weight_total,
status_clear_total
SELECT my_data_type_used,
my_per_vehicle_total,
my_binned_vehicle_total,
my_error_vehicle_total,
my_status_vehicle_total,
my_good_weight_total,
my_status_clear_total
FROM SYS.DUAL;
-- execute the query into the output refcursor
OPEN report_data FOR
my_report_data_statement;
OPEN chart_data FOR
my_chart_data_statement;
OPEN footer_data FOR
SELECT data_type_used,
per_vehicle_total,
binned_vehicle_total,
error_vehicle_total,
status_vehicle_total,
good_weight_total,
status_clear_total
FROM edr_rpt_tmp_veh_totals_table;
END edr_rpt_gen_error_by_hour;
END edr_rpt_error_by_hour_package;
{code}Hi,
Thx for the reply.
As the store proc is inside the package and its invoked in visual studio.
I used to compile the pkg in SQL plus and it throws the error as ' wrong number or types of argument in a call to the stored proc 'edr_rpt_gen_error_by_hour'
As I'm new to pl/sql programming , i really dont know how to pass value to the input parameter.
Edited by: user10641405 on Nov 18, 2009 7:27 PM
Edited by: user10641405 on Nov 18, 2009 7:29 PM -
Procedure with variable number of columns
Hi, I have a procedure that looks like this:
PROCEDURE PROC(p_cursor OUT sys_refcursor)
And in the procedure, I build up QUERY dynamically and the number of columns varies at runtime.
At the end I do
OPEN p_cursor for QUERY
Then to call this, I'm doing
call PROC(?)
My question is, how would I go about running the query from this procedure, then adding rows or modifying the existing results, then returning the modified data?
What I want to do is add a new row based on some condition, so I still need to return a variable number of columns, but I need to modify the results before I return them.
Is there any way of doing this? I need to do some calculations on the columns (the variable columns), create a new row, insert into result set, and return this new result set.A sys_refcursor is ideally suited to pass back to a front end gui like .NET or Java which can then use that cursor to retrieve the data.
In PL/SQL there is no point in using a sys_refcursor unless you know, at design/compile time what the returned columns are going to be.
If the resultant columns are dynamic, then you have no choice but to use the DBMS_SQL package, where you can parse and execute any SQL statement you like and then use the DBMS_SQL package to describe what the resultant columns are and how many there are. From that you can reference the columns by position rather than by name.
e.g.
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_rowcount NUMBER := 0;
BEGIN
-- create a cursor
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement into the cursor
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- execute the cursor
d := DBMS_SQL.EXECUTE(c);
-- Describe the columns returned by the SQL statement
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- Bind local return variables to the various columns based on their types
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); -- Number
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); -- Date
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Any other type return as varchar2
END CASE;
END LOOP;
-- Display what columns are being returned...
DBMS_OUTPUT.PUT_LINE('-- Columns --');
FOR j in 1..col_cnt
LOOP
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
else 'Other' end);
END LOOP;
DBMS_OUTPUT.PUT_LINE('-------------');
-- This part outputs the DATA
LOOP
-- Fetch a row of data through the cursor
v_ret := DBMS_SQL.FETCH_ROWS(c);
-- Exit when no more rows
EXIT WHEN v_ret = 0;
v_rowcount := v_rowcount + 1;
DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
DBMS_OUTPUT.PUT_LINE('--------------');
-- Fetch the value of each column from the row
FOR j in 1..col_cnt
LOOP
-- Fetch each column into the correct data type based on the description of the column
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------');
END LOOP;
-- Close the cursor now we have finished with it
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
DEPTNO - NUMBER
SAL - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
DEPTNO : 10
SAL : 2450
Row: 2
EMPNO : 7839
ENAME : KING
DEPTNO : 10
SAL : 5000
Row: 3
EMPNO : 7934
ENAME : MILLER
DEPTNO : 10
SAL : 1300
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
JOB - VARCHAR2
MGR - NUMBER
HIREDATE - DATE
SAL - NUMBER
COMM - NUMBER
DEPTNO - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
JOB : MANAGER
MGR : 7839
HIREDATE : 09/06/1981 00:00:00
SAL : 2450
COMM :
DEPTNO : 10
Row: 2
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
MGR :
HIREDATE : 17/11/1981 00:00:00
SAL : 5000
COMM :
DEPTNO : 10
Row: 3
EMPNO : 7934
ENAME : MILLER
JOB : CLERK
MGR : 7782
HIREDATE : 23/01/1982 00:00:00
SAL : 1300
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept where deptno = 10');
-- Columns --
DEPTNO - NUMBER
DNAME - VARCHAR2
LOC - VARCHAR2
Row: 1
DEPTNO : 10
DNAME : ACCOUNTING
LOC : NEW YORK
PL/SQL procedure successfully completed.
SQL>In 11g, you can create a sys_refcursor and then the DBMS_SQL package allows you to convert that refcursor into a DBMS_SQL cursor so that you can get the description of the results and do the same. This isn't available prior to 11g though.
However_ before any of that, you should really ask yourself if there is a real need to dynamically be creating queries. There is rarely any real need to do that and if you're finding it's common in your application then this is often a sign of poor design or poorly defined business requirements (leaving the technical side to try and be "flexible" and hence leading to unmaintainable code etc.). -
Number of records in 30 minutes interval.
Hi All,
I am trying to find number of records in 30 minutes of interval. Being said that, i am trying to find out number of records i am getting in 30 minutes. In my table i have a column called "Last_UPDATE_DATE" with date and time. Can somebody help me, possible way to achive. I tried to think through on how to get, but not getting required information.And this is yet another solution:
with timeranges as
select trunc(sysdate)+(level-1)*(30/24/60) starttime
, trunc(sysdate)+(level)*(30/24/60) endtime
from dual connect by level <= (24*2)
select TO_CHAR(b.starttime, 'MM/DD/YYYY HH24:MI:SS') starttime
, TO_CHAR(b.endtime, 'MM/DD/YYYY HH24:MI:SS') endtime
, (select count(*)
from abc a
where a.last_update_date > b.starttime
and a.last_update_date <= b.endtime
) cnt
from timeranges b
group by b.starttime, b.endtime
order by b.starttime;
STARTTIME ENDTIME CNT
08/29/2013 00:00:00 08/29/2013 00:30:00 7
08/29/2013 00:30:00 08/29/2013 01:00:00 13
08/29/2013 01:00:00 08/29/2013 01:30:00 0
08/29/2013 01:30:00 08/29/2013 02:00:00 0
08/29/2013 02:00:00 08/29/2013 02:30:00 0
08/29/2013 02:30:00 08/29/2013 03:00:00 0
08/29/2013 03:00:00 08/29/2013 03:30:00 0
08/29/2013 03:30:00 08/29/2013 04:00:00 0
08/29/2013 04:00:00 08/29/2013 04:30:00 0
08/29/2013 04:30:00 08/29/2013 05:00:00 0
08/29/2013 05:00:00 08/29/2013 05:30:00 0
08/29/2013 05:30:00 08/29/2013 06:00:00 0
08/29/2013 06:00:00 08/29/2013 06:30:00 0
08/29/2013 06:30:00 08/29/2013 07:00:00 0
08/29/2013 07:00:00 08/29/2013 07:30:00 0
08/29/2013 07:30:00 08/29/2013 08:00:00 0
08/29/2013 08:00:00 08/29/2013 08:30:00 0
08/29/2013 08:30:00 08/29/2013 09:00:00 0
08/29/2013 09:00:00 08/29/2013 09:30:00 0
08/29/2013 09:30:00 08/29/2013 10:00:00 0
08/29/2013 10:00:00 08/29/2013 10:30:00 0
08/29/2013 10:30:00 08/29/2013 11:00:00 0
08/29/2013 11:00:00 08/29/2013 11:30:00 0
08/29/2013 11:30:00 08/29/2013 12:00:00 0
08/29/2013 12:00:00 08/29/2013 12:30:00 0
08/29/2013 12:30:00 08/29/2013 13:00:00 0
08/29/2013 13:00:00 08/29/2013 13:30:00 0
08/29/2013 13:30:00 08/29/2013 14:00:00 0
08/29/2013 14:00:00 08/29/2013 14:30:00 0
08/29/2013 14:30:00 08/29/2013 15:00:00 0
08/29/2013 15:00:00 08/29/2013 15:30:00 0
08/29/2013 15:30:00 08/29/2013 16:00:00 0
08/29/2013 16:00:00 08/29/2013 16:30:00 0
08/29/2013 16:30:00 08/29/2013 17:00:00 0
08/29/2013 17:00:00 08/29/2013 17:30:00 0
08/29/2013 17:30:00 08/29/2013 18:00:00 0
08/29/2013 18:00:00 08/29/2013 18:30:00 0
08/29/2013 18:30:00 08/29/2013 19:00:00 0
08/29/2013 19:00:00 08/29/2013 19:30:00 0
08/29/2013 19:30:00 08/29/2013 20:00:00 0
08/29/2013 20:00:00 08/29/2013 20:30:00 0
08/29/2013 20:30:00 08/29/2013 21:00:00 0
08/29/2013 21:00:00 08/29/2013 21:30:00 0
08/29/2013 21:30:00 08/29/2013 22:00:00 0
08/29/2013 22:00:00 08/29/2013 22:30:00 0
08/29/2013 22:30:00 08/29/2013 23:00:00 0
08/29/2013 23:00:00 08/29/2013 23:30:00 0
08/29/2013 23:30:00 08/30/2013 00:00:00 0
Regards.
Alberto -
Numeric or value error: character to number conversion error
I'm having problems inserting a value from a date picker field (DD-MON-YYYY HH MI )
i'm submitting this value to a packaged procedure that accepts this field as VARCHAR2 .
on the insert, i do a to_date( P_DATE, 'DD-MON-YYYY HH:MI PM' )
and i get the numeric conversion error.
If I change the to_date on the procedure side, I get the :could not read the end of the format mask - which I've found threads about on this site.
I've tried using HH24 and different formats, but I get one of the two above errors on the insert.
If I don't fill in the datepicker field at all, it works fine.
help is appreciated !
BillHere is the trace anyway:
*** ACTION NAME:(application 4000, page 1) 2004-09-24 12:58:44.052
*** MODULE NAME:(HTML DB) 2004-09-24 12:58:44.052
*** SERVICE NAME:(TOPS) 2004-09-24 12:58:44.052
*** SESSION ID:(151.1) 2004-09-24 12:58:44.052
*** 2004-09-24 12:58:44.052
ksedmp: internal or fatal error
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
Current SQL statement for this session:
declare
rc__ number;
begin
owa.init_cgi_env(:n__,:nm__,:v__);
htp.HTBUF_LEN := 255;
null;
null;
null;
null;
f(p=>:p);
if (wpg_docload.is_file_download) then
rc__ := 1;
wpg_docload.get_download_file(:doc_info);
null;
null;
null;
commit;
else
rc__ := 0;
null;
null;
null;
commit;
owa.get_page(:data__,:ndata__);
end if;
:rc__ := rc__;
end;
----- PL/SQL Call Stack -----
object line object
handle number name
6A3C4A00 532 package body FLOWS_010500.WWV_FLOW_UTILITIES
6A3C4A00 2502 package body FLOWS_010500.WWV_FLOW_UTILITIES
6A3C4A00 2748 package body FLOWS_010500.WWV_FLOW_UTILITIES
6A0E63C8 991 package body FLOWS_010500.WWV_FLOW_FORMS
6A11675C 932 package body FLOWS_010500.WWV_FLOW_DISP_PAGE_PLUGS
6A11675C 247 package body FLOWS_010500.WWV_FLOW_DISP_PAGE_PLUGS
6A4B54E0 8341 package body FLOWS_010500.WWV_FLOW
6A2A99F0 102 procedure FLOWS_010500.F
6A2B9E54 10 anonymous block
----- Call Stack Trace -----
calling call entry argument values in hex
location type point (? means dubious value)
ksedmp+524 CALLrel ksedst+0 1
ksedmptracecb+15 CALLrel _ksedmp+0 C
_ksddoa+118 CALLreg 00000000 C
ksdpcg+143 CALLrel ksddoa+0
ksdpec+180 CALLrel ksdpcg+0 1966 6D7D208 1
__PGOSF3__ksfpec+11 CALLrel _ksdpec+0 0
8
_kgerev+77 CALLreg 00000000 7474210 1966
kgerec1+18 CALLrel kgerev+0 7474210 6DCE5EC 1966 1
6D7D260
peirve+465 CALLrel kgerec1+0
pevmCVTCN+346 CALLrel _peirve+0
pfrinstrCVTCN+36 CALLrel pevmCVTCN+0 6E6E604 71CE370 7160F0C
pfrrunno_tool+51 CALL??? 00000000
pfrrun+1834 CALLrel pfrrun_no_tool+0 6E6E604 6A3C010A 6E6E640
plsqlrun+1051 CALLrel _pfrrun+0 6E6E604
peicnt+179 CALLrel plsql_run+0 6E6E604 1 0
kkxexe+477 CALLrel peicnt+0
opiexe+4896 CALLrel kkxexe+0 6A2B9E54
kpoal8+1705 CALLrel opiexe+0 49 3 6D7E06C
_opiodr+977 CALLreg 00000000 5E 14 6D7E7CC
_ttcpip+1827 CALLreg 00000000 5E 14 6D7E7CC 0
_opitsk+1098 CALL??? 00000000
opiino+938 CALLrel opitsk+0 0 0 747ABC0 6DEFB14 D8 0
_opiodr+977 CALLreg 00000000 3C 4 6D7FBBC
opidrv+479 CALLrel opiodr+0 3C 4 6D7FBBC 0
sou2o+45 CALLrel opidrv+0 3C 4 6D7FBBC
opimai+237 CALLrel sou2o+0
OracleThreadStart@ CALLrel opimai+0
4+899
77E7D338 CALLreg 00000000 -
Using column number inplace of column name in SQL Select statement
Is there a way to run sql select statements with column numbers in
place of column names?
Current SQL
select AddressId,Name,City from AddressIs this possible
select 1,2,5 from AddressThanks in Advanceuser10962462 wrote:
well, ok, it's not possible with SQL, but how about PL/SQL?As mentioned, using DBMS_SQL you can only really use positional notation... and you can also use those positions to get the other information such as what the column is called, what it's datatype is etc.
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_rowcount NUMBER := 0;
BEGIN
-- create a cursor
c := DBMS_SQL.OPEN_CURSOR;
-- parse the SQL statement into the cursor
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
-- execute the cursor
d := DBMS_SQL.EXECUTE(c);
-- Describe the columns returned by the SQL statement
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
-- Bind local return variables to the various columns based on their types
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Varchar2
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val); -- Number
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val); -- Date
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000); -- Any other type return as varchar2
END CASE;
END LOOP;
-- Display what columns are being returned...
DBMS_OUTPUT.PUT_LINE('-- Columns --');
FOR j in 1..col_cnt
LOOP
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' - '||case rec_tab(j).col_type when 1 then 'VARCHAR2'
when 2 then 'NUMBER'
when 12 then 'DATE'
else 'Other' end);
END LOOP;
DBMS_OUTPUT.PUT_LINE('-------------');
-- This part outputs the DATA
LOOP
-- Fetch a row of data through the cursor
v_ret := DBMS_SQL.FETCH_ROWS(c);
-- Exit when no more rows
EXIT WHEN v_ret = 0;
v_rowcount := v_rowcount + 1;
DBMS_OUTPUT.PUT_LINE('Row: '||v_rowcount);
DBMS_OUTPUT.PUT_LINE('--------------');
-- Fetch the value of each column from the row
FOR j in 1..col_cnt
LOOP
-- Fetch each column into the correct data type based on the description of the column
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_n_val);
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'));
ELSE
DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
DBMS_OUTPUT.PUT_LINE(rec_tab(j).col_name||' : '||v_v_val);
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------');
END LOOP;
-- Close the cursor now we have finished with it
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select empno, ename, deptno, sal from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
DEPTNO - NUMBER
SAL - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
DEPTNO : 10
SAL : 2450
Row: 2
EMPNO : 7839
ENAME : KING
DEPTNO : 10
SAL : 5000
Row: 3
EMPNO : 7934
ENAME : MILLER
DEPTNO : 10
SAL : 1300
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from emp where deptno = 10');
-- Columns --
EMPNO - NUMBER
ENAME - VARCHAR2
JOB - VARCHAR2
MGR - NUMBER
HIREDATE - DATE
SAL - NUMBER
COMM - NUMBER
DEPTNO - NUMBER
Row: 1
EMPNO : 7782
ENAME : CLARK
JOB : MANAGER
MGR : 7839
HIREDATE : 09/06/1981 00:00:00
SAL : 2450
COMM :
DEPTNO : 10
Row: 2
EMPNO : 7839
ENAME : KING
JOB : PRESIDENT
MGR :
HIREDATE : 17/11/1981 00:00:00
SAL : 5000
COMM :
DEPTNO : 10
Row: 3
EMPNO : 7934
ENAME : MILLER
JOB : CLERK
MGR : 7782
HIREDATE : 23/01/1982 00:00:00
SAL : 1300
COMM :
DEPTNO : 10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept where deptno = 10');
-- Columns --
DEPTNO - NUMBER
DNAME - VARCHAR2
LOC - VARCHAR2
Row: 1
DEPTNO : 10
DNAME : ACCOUNTING
LOC : NEW YORK
PL/SQL procedure successfully completed.
SQL> -
Query to retrieve the number of transactions done in every 1 hour for last
Hi,
Could anyone help in writing a query to retrieve the number of transactions done in every 1 hour for last month.
Case:
I/P
Cases Timestamp1
case1 01-01-2008 00:00:01
case2 01-01-2008 00:01:01
case3 01-01-2008 01:00:01
case1 01-01-2008 01:02:01
case4 01-01-2008 01:10:01
case5 02-01-2008 02:00:01
case6 02-01-2008 02:10:01
case7 02-01-2008 23:00:01
case.. 31-01-2008 24:00:00
O/P
from time to_time cases
01-01-2008 00:00:00 01-01-2008 01:00:00 2
01-01-2008 01:00:01 01-01-2008 02:00:00 3
etc
Any help really appreciatedWe can do this using analytical functions
Following is what I did:
create table timestamp1 (ts date)
select *from timestamp1
30/10/2008 15:41:13
30/10/2008 15:41:05
30/10/2008 15:40:03
30/10/2008 14:58:26
30/10/2008 14:29:45
30/10/2008 13:17:48
30/10/2008 08:29:50
30/10/2008 06:05:51
30/10/2008 03:41:52
30/10/2008 02:29:54
select distinct to_char(ts,'hh24') frmhrs,
to_char(ts,'hh24')+1 tohrs, count(ts) OVER (order by to_number(to_char(ts,'hh24')) RANGE (1/24) PRECEDING )
from timestamp1
where trunc(ts)=trunc(sysdate) -- I added this just to make sure I get for today's data
order by frmhrs
FRMHRS TOHRS CNT
02 3 1
03 4 1
06 7 1
08 9 1
13 14 1
14 15 2
15 16 3
You can customizeas per ur need.
Maybe you are looking for
-
Characters show up as boxes when using AWT components.
Having installed on a Windows XP english OS the asian languages packs (with fonts included, from Microsoft) and knowing that with MS Gothic, Gulim and Simsun you can display japanese, korean and chinese characters it seems that on JRE 1.5 and up this
-
How to convert date??
guys if i have a date in the format 2632006 which represents 26th march 2006... how do i convert it into 2006-03-26? is there anyway that i can do it? It may be of a String type..
-
Hi All, I am working on Controller Extension. I extend controller but whenever i do personalize particular controller i cann't identified that controller name. how to identify the controller name. Narayana
-
Hola all, Can someone summarize the benefits and the usage of SQL 05 Clustered Environment? Our sceneiro, we will have one CF server and 2 SQL servers in a clustered environment. Which one of the SQL 05, we should configure as data source? or it does
-
International Address for customer
Hi We need to maintain the customer master address in multiple languages and to do so wish to activate international versions of address. If we do so and address can be maintained in Japanese fonts like Kanji, if standard SAP has a CHAR40 field, will