tags:

views:

129

answers:

4

I have a relatively simple select statement in a VB6 program that I have to maintain. (Suppress your natural tendency to shudder; I inherited the thing, I didn't write it.)

The statement is straightforward (reformatted for clarity):

select distinct 
   b.ip_address 
from 
   code_table a, 
   location b 
where 
   a.code_item = b.which_id and 
   a.location_type_code = '15' and 
   a.code_status = 'R'

The table in question returns a list of IP addresses from the database. The key column in question is code_status. Some time ago, we realized that one of the IP addresses was no longer valid, so we changed its status to I (invalid) to exclude it from appearing in the query's results.

When you execute the query above in SQL Plus, or in SQL Developer, everything is fine. But when you execute it from VB6, the check against code_status is ignored, and the invalid IP address appears in the result set.

My first guess was that the results were cached somewhere. But, not being an Oracle expert, I have no idea where to look.

This is ancient VB6 code. The SQL is embedded in the application. At the moment, I don't have time to rewrite it as a stored procedure. (I will some day, given the chance.) But, I need to know what would cause this disparity in behavior and how to eliminate it. If it's happening here, it's likely happening somewhere else.

If anyone can suggest a good place to look, I'd be very appreciative.

+3  A: 

Some random ideas:

  • Are you sure you committed the changes that invalidate the ip-address? Can someone else (using another db connection / user) see the changed code_status?

  • Are you sure that the results are not modified after they are returned from the database?

  • Are you sure that you are using the "same" database connection in SQLPlus as in the code (database, user etc.)?

  • Are you sure that that is indeed the SQL sent to the database? (You may check by tracing on the Oracle server or by debugging the VB code). Reformatting may have changed "something".

Off the top of my head I can't think of any "caching" that might "re-insert" the unwanted ip. Hope something from the above gives you some ideas on where to look at.

IronGoofy
Of the four suggestions, COMMIT is ringing a bell. I know I executed an update statement in SQL Developer, and that I can select the correctly modified result set afterwards. But from the client, the undesired records are still coming out. (cont'd)
Mike Hofer
Perhaps I need to commit the change to the database after I have executed the update. I'm not using a transaction or anything (it was a simple UPDATE statement in SQL Developer), so I didn't think it was necessary, but Oracle, as we know, is not like SQL Server in the slightest.
Mike Hofer
Everything is a transaction in Oracle, so does need to be committed. Generally if you exit cleanly from something like SQL*Plus or SQL Developer it will commit your changes.
Gary
'Autocommit' is something better not to rely on ... Double check that when you open a new SQLDeveloper, you can still see the changes you made. If you need, do the update again, then COMMIT.
IronGoofy
A: 

In addition to the suggestions that IronGoofy has made, have you tried swapping round the last two clauses?

where
   a.code_item = b.wich_id and
   a.code_status = 'R' and
   a.location_type_code = '15'

If you get a different set of results then this might point to some sort of wrangling going on that results in dodgy SQL actually be sent to the database.

Carl
I gave your answer a shot and there was no difference in the result set. :-/
Mike Hofer
A: 

There are Oracle bugs that result in incorrect answers. This surely isn't one of those times. Usually they involve some bizarre combination of views and functions and dblinks and lunar phases...

It's not cached anywhere. Oracle doesn't cache results until 11 and even then it knows to change the cache when the answer may change.

I would guess this is a data issue. You have a DISTINCT on the IP address in the query, why? If there's no unique constraint, there may be more than one copy of your IP address and you only fixed one of them.

And your Code_status is in a completely different table from your IP addresses. You set the status to "I" in the code table and you get the list of IPs from the Location table.

Stop thinking zebras and start thinking horses. This is almost certainly just data you do not fully understand.

Run this

select 
   a.location_type_code, 
   a.code_status 
from 
   code_table a, 
   location b 
where 
   a.code_item = b.which_id and 
   b.ip_address = <the one you think you fixed>

I bet you get one row with an 'I' and another row with an 'R'

I would think that if this were a data issue, it would produce the same results on both the server and the client. *scratching head* I am more inclined to think that it is something about either my connection, the adapter I'm using, or a failure to commit the change.
Mike Hofer
Then again, I'm no Oracle expert, and Oracle has yet to cease to amaze me with its seemingly endless stream of counter-intuitive design decisions. I chuckle every time I find them bragging about their "ANSI Compliance."
Mike Hofer
Yeh, true about the results being different. Did you run that query? If that doesn't show it, I'd look at driver/client - upgrade.
Things are only counter-intuitive if you already have an intuition that leans in one direction. You weren't born with an intuition toward RDBMS, it developed. I think that MSSS has made lots of equally counter-intuitive decisions. I wish they'd remove ANSI syntax entirely, nothing I hate more.
A: 

I'd suggest you have a look at the V$SQL system view to confirm that the query you believe the VB6 code is running is actually the query it is running.

Something along the lines of

select sql_text, fetches
where sql_text like '%ip_address%'

Verify that the SQL_TEXT is the one you expect and that the FETCHES count goes up as you execute the code.

Gary