Oracle Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsDatabasesOracle Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old January 14th, 2004, 11:25 AM
cheesyhoward cheesyhoward is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 6 cheesyhoward User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 m 15 sec
Reputation Power: 0
Function behaves differently when put in the where clause appose to as column heading

I have a pl/sql function which resides on the database server which is called from within a select statement in an application on the client machine.

select latitude, longitude from scatter where latlong(latitude, longitude)=1;

For each row in the scatter table the fields for the latitude and longitude values are input to the function latlong which compares them to reference latitude longitude points. If the current row is the first row in the table the reference points are assigned to the current values and 1 is returned. For the second ++ rows in the table, if either of the compared latitude / longitude points are >0.005 from the ref points then a 1 is returned and the row is included in the output from the select statement. Another if statement is used to check if the user has begun a new select statement so that the reference points are reset.

The function is within a package so that global variables can be used to remember the reference points since the function is executed for each row in the table.

The current code is…

create or replace package globalLL is
refLat number(32,10);
refLong number(32,10);
refID number(32,10);
function latLong(latitude in number, longitude in number, ID in number) return number;
end;
/

create or replace package body globalLL as
function latLong(latitude in number, longitude in number, ID in number) return number is
compLat number(32,10);
compLong number(32,10);
begin
if refLat is null and refLong is null and refID is null then
-- set default value of refLat and refLong and refID
refLat := latitude;
refLong := longitude;
refID := ID;
return 1;
end if;
if ID < refID then
-- checks if user has chosen a new table or reselected the same table and resets global variables
refLat := latitude;
refLong := longitude;
refID := ID;
return 1;
end if;
refID := ID;
compLat := abs(refLat – latitude);
compLong := abs(refLong – longitude);
if compLat > 0.005 or compLong > 0.005 then
refLat := latitude;
refLong := longitude;
return 1;
else
return 0;
end if;
end;


Now for the problem, if I do this select statement from SQL plus or the application

1)
select seq, latitude, longitude, globalLL.latLong (latitude, longitude, seq)
from scatter;

I get a result containing all of the rows in the scatter table and an indication of which would be not included (0) and which would be included (1) if I ran the following select statement.

2)
select latitude, longitude, seq
from scatter where globalLL.latLong (latitude, longitude, seq)=1

I counted the number of rows with 1s in the globalLL.latLong column for the result from sql statement 1 manually and there were 45.

When I run the 2nd sql statement it does not agree with my manual count. It returns a result containing 86 rows. This is incorrect because it should be 45!

From analysis of the two data sets in my application, when the function runs in the 2nd select statement it is appears as though the number of rows (that the function returns 0 to) between a row that returns 1 and another row that returns 1 is important. It seems when this is large the function resets itself and outputs a 1 when it really should output a 0.

Eg if works ok if row 200 returns 1 and then there are 100 rows that return 0 before the 301st row returns 1. This seems to work ok. But if row 500 returns 1 and then there are 500 rows that return 0 before the 1001st row returns 1, then extra 1s are returned in the middle when they should be 0 and hence increasing my count from 45 to 86. The lat / long distance between row 200 and 301 is the same as row 500 to 1000. There is just more points data points in the second distance.

I do not think it is a problem with the function itself but some options on oracle. Does it limit how many times a function can be run within a package. It is strange that this problem only occurs when the function is put within the ‘where’ clause of the select statement (sql 2) appose to as a column (sql 1).

Any ideas would be much appreciated.

Howard

Reply With Quote
  #2  
Old January 15th, 2004, 08:00 AM
cheesyhoward cheesyhoward is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jan 2004
Posts: 6 cheesyhoward User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 m 15 sec
Reputation Power: 0
Ok I think I have found the problem. I have two tables containing the same data. Scatter 3 is not ordered by sequence number. Scatter 4 is already ordered by sequence number.

The sql query needs to order the table by seq before applying the function to it. Since the sequence number represents the time order that the samples for latitude and longitude were collected it is important that the function processes the data in sequence order.

select latitude, longitude, seq
from (select * from scatter3 order by seq)
where globalLL.latLong (latitude, longitude, seq)=1

returns 86 == should be 45

The sql above seems to apply the function to the unordered list and then orders the results at the end of the query and not in the nested query. This is what produces the extra results because it is comparing the row at sequence number 100 with row 150 instead of 101.


select latitude, longitude, seq
from (select * from scatter4 order by seq)
where globalLL.latLong (latitude, longitude, seq)=1

returns 45 == verified by hand

The sql above returns the correct amount of results. I guess the nested order by seq is being ignored as in the sql for scatter 3. Even though scatter 4 is already ordered the nested part is included to show the ambiguity in my sql statement for scatter 3.
The tables scatter 3 and 4 are a sample from my original scatter table that contains a lot more data and additional columns which prevents me from permanently ordering it by seq.

Therefore how do I make oracle order the scatter3 table before running the function in the where clause?

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesOracle Development > Function behaves differently when put in the where clause appose to as column heading


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway