SQL code returns triple copies of each row
I want to select from my schema and another schema, and sum(total period_activity_a). the code returns triplicate copies of each row, how can I avoid the triplicate rows. I need just one row for each row.
select a.segment3, b.descr, b.leader, sum(a.period_activity_a) from payman.snp_op_detail a,
hrman.organisation_t b
where a.segment3 = b.org_member_id and
a.segment3 between 4000 and 5999 and
a.segment2 != 6651 and
a.segment2 between 5400 and 8999 and
a.period_name in ('JAN-11', 'FEB-11', 'MAR-11', 'APR-11', 'MAY-11', 'JUN-11',
'JUL-11', 'AUG-11', 'SEP-11','OCT-11','NOV-11', 'DEC-11')
group by ROLLUP(a.segment3,b.descr, b.leader);
result
SEGMENT3 DESCR LEADER SUM(A.PERIOD_ACTIVITY_A)
4001 CLOSED: RF-CASSAVA MOSAIC DIS. S.SHOLOLA 0
4001 CLOSED: RF-CASSAVA MOSAIC DIS. 0
4001 0
4005 Closed: BELG. STRAT MUSA-ESARC S.SHOLOLA 0
4005 Closed: BELG. STRAT MUSA-ESARC 0
4005 0
4006 Closed: BELG. STRATEG MUSA KUL S.SHOLOLA 0
4006 Closed: BELG. STRATEG MUSA KUL 0
4006 0
4007 Closed: BELG STRATEG MUSA ONNE S.SHOLOLA 0
4007 Closed: BELG STRATEG MUSA ONNE 0
4007 0
4009 Closed: EEC-OFAR II REIMB EXPs S.SHOLOLA 0
4009 Closed: EEC-OFAR II REIMB EXPs 0
4009 0
Edited by: OlaTunde on 19-Jan-2012 04:41
Hi,
OlaTunde wrote:
I want to select columns and total only not subtotal. the only thing I can think about is rollup. but rollup brings rollup for each column. how can I get total without repeating the rows?Sorry, it's unclear what you want. Whenever you have a problem, post a little sample data (CREATE TABLE and INSERT statements) and the results you want from that data. Explain how you get those results from that data.
If you can show your problem using commonly available tables (such as scott.emp) then you don't need to post any sample data; just the results and the explanation.
Always say which version of Oracle you're using.
As Johan said, GROUP BY (without ROLLUP) produces only one row for each combination of the values in the GROUP BY clause.
Analytic functions can produce the same total as aggregate functions, without changing the number of rows at all.
GROUP BY GROUPING SETS is very flexible about getting subtotals and totals in the same query.
It all depends on your data, what you want from that data, and your version. If you're willing to share what you know about those things, other people will share what they know about SQL.
Similar Messages
-
I'm trying to retrieve data from two different databases in the same server, the code return error. please help me.
select a.segment3, b.descr, b.leader, a.Sum(period_activity_a) from payman.dbo.snp_op_detail a
inner join hrman.dbo.organisation_t b
on a.segment3 = b.org_member_id
where a.segment3 between 4000 and 5999 and
a.segment2 != 6651 and
a.segment2 between 5400 and 8999 and
a.period_name in ('JAN-11', 'FEB-11', 'MAR-11', 'APR-11', 'MAY-11', 'JUN-11', 'JUL-11', 'AUG-11', 'SEP-11','OCT-11','NOV-11')
group by rollup (a.segment3,b.descr);
Edited by: OlaTunde on 19-Jan-2012 01:13Please, whenever you post a question stating "the code return error", then post the complete error stack you get. How can we help if we do not know what error?
Your syntax for accessing other databases looks like MS/SQL syntax to me? That will not work in Oracle. You need a [url http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_5005.htm#i2061505]database link.
When you have the database link, you access data from the other database using something like:
select column_names from schema_name.table_name@dblink_name;(I assume it is two Oracle databases you wish to get data from - otherwise you need to look into heterogenous gateway ;-) ) -
Select count(*) on sql statement returning zero when a matching row exists.
Our account has an ANSI C application that checks for the existence a row on an Oracle table(s) by using the following SQL:
int iCount = 0;
EXEC SQL
SELECT count(rownum) INTO :iCount
FROM sys.all_tab_columns
WHERE table_name IN
(SELECT table_name FROM
sys.all_synonyms
WHERE upper(synonym_name) = upper(:szDestTable))
AND upper(column_name) = upper(:szColumnName)
AND owner = 'DBAUSER';
The bind variables szDestTable and szColumnName are populated with values parsed from columns on another database table. This application is executed through out the day. Occasionally, the application will report a zero in the iCount when there should be a match. I have verified the szDestTable and szColumnName are populated with the correct values which would find a match and they are correct. To make matters even stranger, the application will parse the same input values and find a match (as it should). At some point during the day, and it can be at any time, the application will NOT find a match on the same file, same values. Every subsequent execution of this application will not find a match on the same values. Once the database is brought down and started up in the evening for its normal backups, the application will find a match again on the same values. This problem does not occur every day. I could be a week or a week and a half between incidents.
I printed the contents of the sqlca.sqqlerrm.sqlerrmc field to a log file. The sqlca.sqlerrm.sqlerrmc field reported an ORA-1405 bind variable was null when the iCount was reporting a zero. When I compiled this application, I set the Proc*C flag to UNSAFE_NULLS=yes since there are other bind variable in the application that can be NULL and that is ok.
The above SQL is compiled into the C application using the Proc*C compiler. It is compiled using the Oracle 11.2.0.2 libraries. The application is executed against an Oracle 11.2.0.2 database. The database and application are executed on an HP/Unix 11.31 platform.
This problem did not start occurring until our account went from Oracle 10.2 to Oracle 11.2. Recently, I have changed the SQL to perform a “SELECT COUNT(rownum)” instead of the “SELECT COUNT(*)”. I compiled the application and executed the new application with the SELECT COUNT(rownum) against the same database where the same application with the SELECT COUNT(*) was failing to find a row that actually existed. The application with the SELECT COUNT(rownum) found the matching row as it should have. The new application has been executing in production for about 10 days now without any problems against ten various Oracle 11.2 databases.
Why would SELECT COUNT(*) and SELECT COUNT(rownum) be any different?This forum is about C programming in general, and about using Studio C in particular.
Your question is about Oracle database programming. You are more likely to find a helpful answer in a forum about database programming. Start here:
https://forums.oracle.com/forums/category.jspa?categoryID=18 -
APEX,PDF's, BI Publisher and SQL Query returning SQL code..
I don't know if I should be posting this in this Forum or the BI Publisher forum, so I am posting in BOTH forums..
I love APEX, let me say that first.. And appreciate the support offered here by the group, but am running int a confusing issue when BI Publisher tries to build a report from the above type APEX report..
Here is my dilemma:
I have a number of reports that are part of a Oracle package. They return an SQL Query back to a reports region on a page. I am having to deal with the column names returned are col01, col02..
The issue I have is, when building the Application Level query to download the XML sample from in building RTF layouts in Word, you can not use this code, you MUST use a standard SQL Select.
I have taken the sql from the function returning sql, and copied into the application query, supplying the required data values for bind variables being used in the query.
An XML file is produced, and I use this to build the RTF format file that I load back into APEX and try to use it for the PDF rendering of the report. I can view the output as a PDF in the Word add on, but when I try using it with the report, it is returning an empty PDF file.
Can anyone tell me what error log files on the bi publisher side I can look at to see what error is happening?
Thank you,
Tony Miller
UTMB/EHN
Title adjusted to allow people to know what I am talking about...
Message was edited by:
Tony MillerTony,
You can find the log as follows:
- go to http://[yourserver]:[yourport]/em
- logon to OC4J EM: oc4jadmin/[yourpassword]
- click on "logs" at the bottom of the page
- in the hgrid/tree, expand OC4J->home->Application
xmlpserver
- click on view log icon
You can also observe what's going on in BI Publisher
by going to the command prompt from where you started
it.
Or, as a third option, you can locate the file on
your file system, depending on your setup, the path
would be something similar to this:
\oracle\product\10.2.0\bip\j2ee\home\application-deplo
yments\xmlpserver\application.log
With that said though, I don't expect you'll find
much in there that would help with your particular
problem. I suspect you either get no rows in your XML
at runtime, due to some session state issues, or your
XML structure does in fact not match your RTF
template.
I'm not quite following your problem description,
i.e. when did you do what and are you associating
your report layout with a report query or report
region. So just some general notes, your query needs
to be parseable at design-time, when exporting the
XML, so that you get the XML file with the proper
column names derived from your query. If you want to
use your RTF template with a standard report region,
you must export the XML file first using the advanced
XML structure option. And of course the column names
in your report query need to match the column names
in your report region.
Perhaps this helps you further diagnose what's going
on, if you have additional information that could
help, let me know. And if you could stage this on
apex.oracle.com, I'd be happy to take a look.
Regards,
MarcMarc,
Thanks for looking at this issue. Below find my remarks to your questions..
Re: your query needs
to be parseable at design-time, when exporting the
XML, so that you get the XML file with the proper
column names derived from your query.At the start of this process, the query code was a function in a package. The function was returning an SQL select statement, for a report region on a page. I took the select statement, built an application query to build a sample of the xml for BI Publisher desktop (Add-on for Word). The code was producing the usual Col01, Col02.. since at design time that is were the column names.
When I then took the xml from this and built the rtf for loading into my APEX application.
When testing the Application Query with this RTF report layout, I am getting PDF's. When using it with the report region sending an xml feed to BI Publisher I am getting nothing back.
I have since taken the sql code and moved it back into the report region, and set the region to have a type of straight SQL Query. I have even tried to hard-code the parameters I was getting from the page to limit data returned.
Is it possible to see the xml being produced by the APEX page?
Re: Stage this on apex.oracle.com.. I would love to, but we would have HIPPA issues if I posted the data on a public website.
Can I send you the RTF file and the xml file that the application query is creating to see if there something weird about them?
Thank you,
Tony Miller
UTMB/EHN -
For each row of a table call a pl/sql function
Hi,
i have a search form in adf like this:
parameter1:___
parameter2:____
buttonSearch
Table with results
field1 field2 field3
row1 ------ --------- -------
row2 ------ --------- -------
row3 ------ --------- -------
The user inputs the parameters 1 and 2 then press buttonSearch and the query execute and returns rows 1 to 3.
What i need is for each row call pl/sql function and passed the parameter 1 and 2 and field 1 to 3 (plsql function recives 5 parameters (parameter1, parameter2, field1 , field2 and field3) )
my buttonSearch call a java class that execute ExecuteWithParamters method.
I create the call to my plsql function on Application module class and then export as a java interface.
So i have the function to use in the viewcontroller layer, but i don't know where to use it, and how to pass the paramters: the parameter 1 and 2 that user inputs and the row fields.....
any ideas....
thanks!!Hi,
for this you need to call the PLSQL function upon table rendering, which means that you need a field in the table referencing a managed bean. In the managed bean you can use #{row} and resolve it using a ValueExpression. #{row} gives you access to the current rendered row (this is why you need to do it when the table renders) and thus allows you to call getAttribute(name) to get the values of field 1 - 3. The search field value you should get through the bindings reference (assuming the search form uses ADF). Then you create an operation binding for the executeWithParameters and call operationBindingName.getParamsMap().put(argname, argvalue); on it.
Frank
Ps.: I am concerned about the performance you get and wonder if it isn't possible to create a transient attribute that executes the function and displays the results. As I understand, the search parameters are only to filter the result set, which you still can do -
Using a Table Trigger to Trap Error Codes Returned to a SQL Loader seeion
I would be grateful if anyone knows how to go about this.
I am trying to insert into a table, details of SQL Loader's rejected records by possibly using a trigger on the loading table to try and trap the error code returned to SQL Loader.
What I am trying to achieve is to insert in to a table the load or rejected record details that are in SQL Loaders log file after a load session. For example: records read:, records inserted:, records rejected:...etc..
My main concern is that the loading table is regularly loaded, with 3m records, has 90 columns, and to check by referencing each column's new value, in the table trigger, may mean very long load times.
Anyone got any how to ideas?
Many thanks
Regards
CarlosFolks, thanks for your help.
Previously, I had briefly considered both ideas and they would work.
I dismissed the utl_file package solution because I believed that it would take too long to read in each log file line, search for the text and then inserts it into a table.
I overlooked testing this and when I did (1mb file) it actually was pretty fast. I will go that route.
Thanks for everyones help
regards
Carlos -
Raise expection for each row if returned set contains x
Hello Guys,
I have the following code and almost gave up on the idea to raise an exception and print
a line for each row where the sales price is < 10. I know how this works with a CURSOR but I want to try it without it. Thinking about it let me to the conclusion that this is not possible to act on individual row results on a set based operation. I will have to use a CURSOR (not set based so I can look at each row).
Am I thinking correctly?
(Code example deleted due to confusion)
Code example deleted due to confusion
Edited by: metalray on 10.11.2010 01:07Hi 3360,
I am using PL/SQL. I can make my point without any code.
The question, in a different format is this:
Can I throw an whatever exception (or dbms_output put line) for individual rows WITHOUT using a cursor.
My answer (and I just need clarification on this):
*(1)* No, because anything apart from a cursor is set-based and set-based operations (select, join, union)
can not through exceptions on individual rows.
*(2)* Yes, you can have a DBMS_OUTPUT.PUT_LINE with whatever exception on a set based operation
for each individual row that causes the exception (I dont think this answer is true :)
@Agustin UN, thanks for that. I know that is possible :) The problem is,
that I dont think I can print or fetch each individual row that causes the "exception" since
it is treated as a set. - I am welcome for someone to tell me that it work nevertheless -
SQL to return the row IDs showing in a Paginated region
Hi All,
I am looking for a way to return the RowIDs of the rows that are currently showing in a paginated report Region.
Preferably with SQL but PL/SQL if required.
I found this Topic which comes close but is only for one record:
Re: Connecting a report region and a PL/SQL region
Any help greatly appreciated.
If you would like to know why, see my related post here:
Freeze Panes Functionality
Thanks again
ReubenHi All,
I am looking for a way to return the RowIDs of the rows that are currently showing in a paginated report Region.
Preferably with SQL but PL/SQL if required.
I found this Topic which comes close but is only for one record:
Re: Connecting a report region and a PL/SQL region
Any help greatly appreciated.
If you would like to know why, see my related post here:
Freeze Panes Functionality
Thanks again
Reuben -
SQL merge and after insert or update on ... for each row fires too often?
Hello,
there is a base table, which has a companion history table
- lets say USER_DATA & USER_DATA_HIST.
For each update on USER_DATA there has to be recorded the old condition of the USER_DATA record into the USER_DATA_HIST (insert new record)
- to have the history of changes to USER_DATA.
The first approach was to do the insert for the row trigger:
trigger user_data_tr_aiu after insert or update on user_data for each rowBut the performance was bad, because for a bulk update to USER_DATA, there have been individual inserts per records.
So i tried a trick:
Instead of doing the real insert into USER_DATA_HIST, i collect the USER_DATA_HIST data into a pl/sql collection first.
And later i do a bulk insert for the collection in the USER_DATA_HIST table with stmt trigger:
trigger user_data_tr_ra after insert or update on user_dataBut sometimes i recognize, that the list of entries saved in the pl/sql collection are more than my USER_DATA records being updated.
(BTW, for the update i use SQL merge, because it's driven by another table.)
As there is a uniq tracking_id in USER_DATA record, i could identify, that there are duplicates.
If i sort for the tracking_id and remove duplicate i get exactly the #no of records updated by the SQL merge.
So how comes, that there are duplicates?
I can try to make a sample 'sqlplus' program, but it will take some time.
But maybe somebody knows already about some issues here(?!)
- many thanks!
best regards,
FrankHello
Not sure really. Although it shouldn't take long to do a test case - it only took me 10 mins....
SQL>
SQL> create table USER_DATA
2 ( id number,
3 col1 varchar2(100)
4 )
5 /
Table created.
SQL>
SQL> CREATE TABLE USER_DATA_HIST
2 ( id number,
3 col1 varchar2(100),
4 tmsp timestamp
5 )
6 /
Table created.
SQL>
SQL> CREATE OR REPLACE PACKAGE pkg_audit_user_data
2 IS
3
4 PROCEDURE p_Init;
5
6 PROCEDURE p_Log
7 ( air_UserData IN user_data%ROWTYPE
8 );
9
10 PROCEDURE p_Write;
11 END;
12 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY pkg_audit_user_data
2 IS
3
4 TYPE tt_UserData IS TABLE OF user_data_hist%ROWTYPE INDEX BY BINARY_INTEGER;
5
6 pt_UserData tt_UserData;
7
8 PROCEDURE p_Init
9 IS
10
11 BEGIN
12
13
14 IF pt_UserData.COUNT > 0 THEN
15
16 pt_UserData.DELETE;
17
18 END IF;
19
20 END;
21
22 PROCEDURE p_Log
23 ( air_UserData IN user_data%ROWTYPE
24 )
25 IS
26 ln_Idx BINARY_INTEGER;
27
28 BEGIN
29
30 ln_Idx := pt_UserData.COUNT + 1;
31
32 pt_UserData(ln_Idx).id := air_UserData.id;
33 pt_UserData(ln_Idx).col1 := air_UserData.col1;
34 pt_UserData(ln_Idx).tmsp := SYSTIMESTAMP;
35
36 END;
37
38 PROCEDURE p_Write
39 IS
40
41 BEGIN
42
43 FORALL li_Idx IN INDICES OF pt_UserData
44 INSERT
45 INTO
46 user_data_hist
47 VALUES
48 pt_UserData(li_Idx);
49
50 END;
51 END;
52 /
Package body created.
SQL>
SQL> CREATE OR REPLACE TRIGGER preu_s_user_data BEFORE UPDATE ON user_data
2 DECLARE
3
4 BEGIN
5
6 pkg_audit_user_data.p_Init;
7
8 END;
9 /
Trigger created.
SQL> CREATE OR REPLACE TRIGGER preu_r_user_data BEFORE UPDATE ON user_data
2 FOR EACH ROW
3 DECLARE
4
5 lc_Row user_data%ROWTYPE;
6
7 BEGIN
8
9 lc_Row.id := :NEW.id;
10 lc_Row.col1 := :NEW.col1;
11
12 pkg_audit_user_data.p_Log
13 ( lc_Row
14 );
15
16 END;
17 /
Trigger created.
SQL> CREATE OR REPLACE TRIGGER postu_s_user_data AFTER UPDATE ON user_data
2 DECLARE
3
4 BEGIN
5
6 pkg_audit_user_data.p_Write;
7
8 END;
9 /
Trigger created.
SQL>
SQL>
SQL> insert
2 into
3 user_data
4 select
5 rownum,
6 dbms_random.string('u',20)
7 from
8 dual
9 connect by
10 level <=10
11 /
10 rows created.
SQL> select * from user_data
2 /
ID COL1
1 GVZHKXSSJZHUSLLIDQTO
2 QVNXLTGJXFUDUHGYKANI
3 GTVHDCJAXLJFVTFSPFQI
4 CNVEGOTDLZQJJPVUXWYJ
5 FPOTZAWKMWHNOJMMIOKP
6 BZKHAFATQDBUVFBCOSPT
7 LAQAIDVREFJZWIQFUPMP
8 DXFICIPCBCFTPAPKDGZF
9 KKSMMRAQUORRPUBNJFCK
10 GBLTFZJAOPKFZFCQPGYW
10 rows selected.
SQL> select * from user_data_hist
2 /
no rows selected
SQL>
SQL> MERGE
2 INTO
3 user_data a
4 USING
5 ( SELECT
6 rownum + 8 id,
7 dbms_random.string('u',20) col1
8 FROM
9 dual
10 CONNECT BY
11 level <= 10
12 ) b
13 ON (a.id = b.id)
14 WHEN MATCHED THEN
15 UPDATE SET a.col1 = b.col1
16 WHEN NOT MATCHED THEN
17 INSERT(a.id,a.col1)
18 VALUES (b.id,b.col1)
19 /
10 rows merged.
SQL> select * from user_data_hist
2 /
ID COL1 TMSP
9 XGURXHHZGSUKILYQKBNB 05-AUG-11 10.04.15.577989
10 HLVUTUIFBAKGMXBDJTSL 05-AUG-11 10.04.15.578090
SQL> select * from v$version
2 /
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - ProductionHTH
David -
Calling a stored procedure for each row returned
I need to call a stored procedure for each row returned by a repeating frame. I called the stored procedure from the repeating frame format trigger, but that did not work( it did no populated the tables populated by the stored procedure)
How can I call a stored procedure for each row returned by a repeating frame.
Thank youInclude it as a formula column in your data model.
-
Update button in sql report for each row can only get the report value
I have to added Update for each row of records like:
select a.*,'Update' button from (
select c.*,d.login from country c,champ d
where c.champ_id=d.champ_id(+)
order by c.name) a
then go to the report->edit button ->Column Link
I added some items P40_REGION, P40_CHAMPID,P40_ACTIVE,P40_CODE and assign the value like #region#,#active# ,#code# to these item, but when I click the update button in the report I found the values such as #region#,#active# ,#code# is the report value not the select list selected value(the region, active column are displayed as select list lov).
Can anyone tell me how to sort this knid of problem?
Thanks a lot!Sorry, it doesn't work. I also tried apex_application.g_f01(i), but not everytime I can get the value or get the incorrect value. If you have time you can try to create it like what I have described. Our team use two days now but still can not sort this problem.
-
Create Test data using T-SQl script for each row
Hi team,
I am looking for a sql code snippet which read data from below table
UserId username contact
1 Anil 111
2 Sunil 222
and insert data to below table with some test data appending sequence number 1,2,3 for only City and Email. Both are different tables
and does not have any referencial integrity
No of records inserted for user is configurable for example count = 3
Username City Email
Anil city1 email1
Anil city2 email2
Anil city3 email3
Sunil city1 email1
Sunil city2 email2
Sunil city3 email3DECLARE @cnt INT=3
DECLARE @Users TABLE(UserId INT, UserName VARCHAR(99),Contact INT)
INSERT INTO @Users VALUES
(1,'Anil',111),
(2,'Sunil',222)
SELECT UserName,'city'+CAST(num AS varchar(10)) city FROM @Users
CROSS APPLY
SELECT TOP(@cnt) number +1 AS num
FROM master..spt_values
WHERE type = 'P') AS Der
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence -
T1 (Table and columns & data ) used in my example
create table T1 (col1 number,col2 number);
col1 col2
1 5
2 5
3 5
4 5
11 6
12 6
13 6
14 6
CREATE OR REPLACE FUNCTION TEST (par NUMBER) RETURN VARCHAR2 IS
l_concat VARCHAR2(32767) ;
BEGIN
select wm_concat(col1) into l_concat from t1 where col2=par;
RETURN l_concat;
END;
select TEST(5) from dual;
The above example always returns a NULL as opposed to (1,2,3,4);
CREATE OR REPLACE FUNCTION TEST (par NUMBER) RETURN VARCHAR2 IS
l_concat VARCHAR2(32767) ;
l_str varchar2(32767);
BEGIN
l_str:='select wm_concat(col1) from t1 where col2=:b';
execute immediate l_str into l_concat using par;
RETURN l_concat;
END;
select TEST(5) from dual;
This returns the correct answer .i.e. (1,2,3,4);
My question is why my first code returning NULL? Is there any restriction using aggregate functions inside
plsql code ?BluShadow wrote:
The in paramter has the same name as one of the column . Thus the select query was not taking the filtering predicate as the in parameter col1 ,rather it was
using the column's value for filtering each row and hence the wm_concat was not getting any row to concatenate .That's why you should use a good coding standard and perhaps prefix parameters with "p" or "p_" and local variables with "v" or "v_" etc.Smacks too much of archaic Hungarian notation. :-)
Explicit scope definition is supported by PL/SQL. So why invent a new manual standard for scope, when there exists one already?
SQL> create or replace procedure FooProc( empNo emp.empno%Type ) is
2 empRow emp%RowType;
3 begin
4 select
5 e.* into empRow
6 from emp e
7 where e.empno = FooProc.empNo;
8
9 dbms_output.put_line(
10 'Employee '||empNo||' is '||empRow.ename||
11 ', and employed as '||empRow.job
12 );
13 end;
14 /
Procedure created.
SQL>
SQL>
SQL> exec FooProc(7369)
Employee 7369 is SMITH, and employed as CLERK
PL/SQL procedure successfully completed.
SQL> Personally, I find the v_ and p_ prefix approach quite silly - attempting to address an issue that is already solved by explicit PL/SQL scope.
Never mind that the approach of using different prefixes, attempts to identify scope - and goes down the exact same slippery scope that Hungarian notation did. Which resulted in the death of this misguided standard, many years ago.
Frustrates me to no end to see the exact SAME mistakes made in PL/SQL that were made a decade or more ago - where lessons learned since then are conveniently ignored when it comes to PL/SQL programming.
It is still seems to be the Dark Ages when it comes to PL/SQL development.... :-( -
Hi guys:
I'm not an expert in SQL and I saw what Apex is doing is very useful.
Can I see the SQL code generated by Apex -by woking in Apex environment-With a little research on tracing, you should be able to easily get back the SQL statements that APEX uses, but not the PL/SQL. The PL/SQL is wrapped, so you won't be able to see that. With that said, the SQL is nothing special. That's is not a knock on the APEX team (I used to be on it), it's just nothing you couldn't find examples of throughout asktom.oracle.com.
The APEX Team follows some pretty simple and well known design principals that keeps the code very efficient. Above all else, the principal of designing the data structures for how they'll be accessed, not how they make sense to the developers is key. Since the nature of the APEX data structures is 95% read, they may make the edit of a page less efficient and do some extra work up front to make the display of that page as efficient and fast as possible.
In keeping with that theme, they will create indexes on tables that makes the reads as fast as possible, but again may make the create / edit of a page much slower due to additional index maintenance.
You'll notice that all of the tables have a single primary key column; none of this 3 column composite key stuff you see discussed all over this forum. This makes foreign keys, queries, updates, and deletes much easier on the programmers. I've stopped responding to the questions about DML on tables with 3+ composite key columns or tables with no primary key at all. IMHO it's just not good database design, but people get very defensive of their data models. So, I've given up. My advise to you is to stick with a single, random primary key that will never ever be changed. Also please ignore the flame war this is likely to start in this thread ;)
I'm also a big believer in instrumenting your code. This is definately Tom Kyte's influence on me, but also the APEX team's. Notice that APEX has a debug mode with timing, so they've clearly instrumented their code. You can see an example of this in a wiki project I'm working on now. Take a look at this package. Notice how every procedure in there has 2 "$IF $$debug $THEN" blocks, 1 at the beginning and one at the end. This is using conditional compilation and allows me to recompile this package with debug on so I can see how much time each procedure is taking. I can't stress this enough, instrument your code.
Other good SQL principals to keep in mind include:
- Don't call functions in SQL predicates (where clauses) as it's VERY slow. If you need to call a function such as upper, make sure you use a function-based index on that column.
- Do everything in bulk SQL operations that you can. A lot of people resort to PL/SQL loops for processing. Tom Kyte refers to this as "row-by-row or slow-by-slow".
- Don't call functions in SQL at all if you are returning a lot of rows. That function will be called once for every row and you'll context switch between SQL and PL/SQL once for every row.
- For your most popular queries, particularly on "wide" tables, if you index every column in the select and predicates section, the data can be returned from just the index without going back to the table.
- Materialized views are your friend when you want to pre-compute the answers to your most expensive questions.
- Buy Tom Kyte's books. This is not a commercial for them, but the philosophy contained in those books has absolutely influenced the philosophy of the APEX team... They all used to work together on a daily basis.
Hope this helps,
Tyler -
PL/SQL code written in db or in application...????
Hi ,
Which is the best...at performance , maintability... e.t.c.???
To write PL/SQL as validation process of data values going to be inserted in db:
1) as db trigger (before insert or update row-level trigger)
2) in application level - in Forms10g...
This PL/SQL code compares some pairs of data values only.... there DML statement....
Both db server and App server are considered to be or in the same machine or in two machines very close to each other...
Note: i use Db10g .
Thanks...
SimIt is all about moving parts. How many there are. Where they are located.
The less moving parts, the less the complexity, the bugs - and the better the performance (less wheels to turn to crunch data), the easier the maintenance and the better the flexibility.
Part of this is having the moving parts close to the data. Kind of obvious - what is faster? Shipping data from the db engine to a front-end application via a app server and web server? Or shipping the data from the db (SQL) engine to a PL/SQL process running as part and parcel of db instance? IPC is significantly faster than TCP/IP.
Having the moving parts close to the data also means that it can scale with the data. Oracle is good at scalability. It is designed at its very core to be scalable. Partitions to reduce I/O. Shared Server to reduce o/s resource footprint per client session. Shared pool to re-use SQL. DB buffer to cache data. RAC to run multiple db instances for a single physical database. Etc. Etc.
With the application moving parts being close to the data, it inherits this scalability. You can "multi-thread" application code using table pipelines. You have access to forking application code using background processes (DBMS_JOB and DBMS_SCHEDULER). You have bulk processing in order to transfer more data per SQL engine call, between the buffer cache and your application, and thus also reduce expensive context switching.
This list goes on and on.
All this is summarised into the following rules.
Rule 1. Do it in SQL.
Rule 2. Only when SQL cannot do it, use PL/SQL. (e.g. SQL is not suited for managing and controlling process flow - PL/SQL is)
Rule 3. Only when PL/SQL cannot do it, use <insert-language-here> (e.g. PL/SQL cannot render a Windows grid on the client - but Delphi/C#//Java can).
Also keep in mind that in the modern client-server paradigm we deal with a web architecture. Which means the client is a web browser. And this means that PL/SQL can pass the data (HTML) required by the client (web browser) to render the User Interface.
Have a look at APEX (Oracle's Application Express) for how this works. http://apex.oracle.com
All you need to develop web applications is APEX (a PL/SQL product suite in the database) and a web browser. Kickass stuff... :-)
Maybe you are looking for
-
Dear All, Is there any function from which I can get Material Stock as on Particular Key Date. e.g. I want to see the stock of X material on 31.03.2009. And also any function from which i can get Batch Stock as on particular Key date: e.g. Material
-
Why can't I read a book purchased through iPhone ibook app on my MacBook Pro?
Why can't I read a book purchased through iPhone ibook app on my MacBook Pro? Also, is there any way to print pages from book?
-
Hi i want to use boolean type in a procedure as out parameter !!
Hi I need to use Boolean type as out parameter in my procedure which return true if the SELECT query in procedure returns any row otherwise it should return false please HELP !!
-
How to transfer files from virtual machine to host machine
Hello, I want to know how to copy files from virtual machine o host machine while the virtual machine running. I can't share files from virtual machine because i am just studying for mcsa in company computer. I can't connect my virtual machine to sa
-
It gave me an error saying that there was an error communicating with the drive but the burn dialog box is still there since over an hour and refuses to go away. I pressed stop button on it and its still going. but it does not display any progress(si