Well I am querying my DB, a table called bookBilling, to get a value under the column of billingID.
In my first query I get the customer ID from a table based on what value the cookie holds.
In my second query I take that custID value and am looking to get the billingID associated with it.
query = "SELECT custID FROM bookSession WHERE session='"&theCookie&"'"
'--Connect to DB'
Set objConn = ConnectDB()
'--Query to DB'
Set objRS = objConn.Execute(query)
custID = objRS.Fields("custID")
query = "SELECT billingID FROM bookBilling WHERE custID="&custID&""
objConn.Execute(query)
Here is where it becomes an issue. I tried using this to obtain the value:
billingID = objRS.Fields("billingID")
When that didn't work I printed the query to my browser to make sure it worked and it came back good, I checked it in SQL Server Management Studio to make sure. After that I decided to play with it a bit and found that using "0" as the reference works since it is the first item in my table.
billingID = objRS.Fields(0)
So that worked, I know my table column header is correct I have looked at it and used it in other queries before. Does anyone know why this might happen? Is it a result of not clearing my connection or closing it afterward?
Thanks
Hey, is it a typo that you don't have this?
query = "SELECT billingID FROM bookBilling WHERE custID="&custID&""
objRS = objConn.Execute(query)
To reload the recordset with the data and definition of the second query.....
Just a thought, try Setting/Instantiating the ObjRS to a Recordset first, then apply the query.execute to it after, rather than the initial all in one with the first CustId query
Running two separate queries is slow anyway. It's almost always faster to combine them into one statement:
SELECT billingID
FROM bookBilling bb
INNER JOIN bookSession bs ON bs.custID=bb.custID
WHERE bs.session= #theCookie
Also: cookies are just text files, and anyone can edit a text file. If you substitute a cookie value directly in your query like that there is the potential for sql injection. It's not the normal attack vector, but it's still possible.
As to your specific error, you execute the 2nd query directly from the connection rather than opening it in the record set:
objConn.Execute(query)
I'm surprised you get anything at all, and I expect the value you're seeing in objRS.Fields(0) is probably just the custID from the previous query. But that all becomes moot if you consolidate the queries like I recommended.
query = "SELECT billingID FROM bookBilling WHERE custID="&custID&""
objConn.Execute(query)
You're not opening a resordset for that second query.
And, not sure if that has any influence at all, but I never name my queries identical. To be sure I guess.
Edit, well that's kind of what the people above me said, I'm a Slowpoke.
Damn, yes it was a typo. I'm not sure I understand why it worked using the column number still but not the column name even though I didn't open the recordset.
#Joel Coehoorn
Thanks for the info on inner joining the queries. My teacher has been telling us to do that but I have not really understood it enough to do it until I saw that.
For my table I can't really use it though because there isn't necessarily a billingID upon registration so I would run into some "EOF's" occasionally.
Thanks everyone!
Related
I need to replace all occurrences "google.com" that are met in the SQL db table Column1 with "newurl". It can be a full cell value, a part of it (substring of varchar()), can be met even several times in a cell.
Based on SO answer search-and-replace-part-of-string-in-database
this is what I need:
UPDATE
MyTable
SET
Column1 = Replace(Column, 'google.com', 'newurl')
WHERE
xxx
However, in that answer it is mentioned that
You will want to be extremely careful when doing this! I highly recommend doing a backup first.
What are the pitfalls of doing this query? Looks like it does the same what any texteditor would do by clicking on Replace All button. I don't think it is possible in my case to check the errors even with reserve copy as I would like to know possible errors in advance.
Any reasons to be careful with this query?
Again, I expect it replaces all occurences of google.com with 'newurl' in the Column1 of MyTable table in the SQL db.
Thank you.
Just create a test table, as a replica of your original source table, complete the update on there and check results.
You would want to do this as good SQL programming practice to ensure you don't mess up columns that should not be updated.
Another thing you can do is get a count of the records before hand that fit the criteria using a SELECT statement.
Run your update statement and if it's a 1-1 match on count, you should be good to go.
The only thing i can think of that would happen negatively in this respect is that additional columns get updated. Your WHERE clause is not specific for us to see, so there's no way to validate that what you're doing will do what you expect it to.
I think the person posting the answer is just being cautious - This will modify the value in Column1 for every row in MyTable, so make sure you mean it when you execute. Another way to be cautious would be to wrap it in a transaction so you could roll it back if you don't like the results.
I'm working with an external access database (.accdb) in VB.NET and I'm trying to limit the amount of times that my [Winforms] program pings the data since it slows it down pretty considerably. I figured I could do this by querying my in-memory dataset instead of continuously going back to the database itself. Though, unfortunately, I cannot seem to figure out how to query my in-memory dataset. I tried looking up LINQ but couldn't find any instructions on how to set it up.
Am I missing something? Is there a better way to do this?
Thanks so much! My starting code below...
locsql = "SELECT * FROM TABLE1)
Dim objAdapter As New OleDb.OleDbDataAdapter(locsql, objconn)
objAdapter.Fill(locdata, "BASE")
So I can easily do some basic things I need with locdata("BASE").rows.item("Item") but I have to do some stuff like
SELECT thing FROM TABLE1 WHERE this = this and that = that and I would just rather not keep going back to the database if possible.
Is it possible?
You need to use the Select method on each datatable you want to query. The syntax is very similar to the part after the WHERE clause in you normal SQL query. IE
locdata.tables(0).Select("ID = 47")
This returns an array of datarows.
If you want to use Linq against a DataTable you need to apply the AsEnumerable method then apply the usual Linq methods.
For example.
If you need to find all the customers having the Field Country equals to 'Canada' and then Sum the total of their Amount column you could write
Dim listOfCanadians = locdata.Tables(0).AsEnumerable() _
.Where(Function(row) row.Field(Of String)("Country") = "Canada") _
.ToList()
Dim totalCanadaAmount = listOfCanadians.Sum(Function(row) row.Field(Of Decimal)("Amount"))
What I ended up doing was breaking down my data filters and creating new tables based on a series of loops and if/else statements. all of these responses were very helpful, just didn't seem to work for what I needed. Thanks everyone!
I am using application builder and setting up select boxes to populate a query that spits out into a report below, I'm having a problem with one populating though, and I can't immediatly see why;
Here's how I'm referencing;
AND CINEMA.LOCATION = :pticketstown
this works fine and pulls in the choice from the select box which is popluated from a query on the cinema table, however when I try and do the same thing for another table, try and pull in a film title from a select box choice - it doesnt seem to work, the rport says no output.
Im setting up the select box the same way, and its pulling in the films, but when as soon as I reference it in the sql report, the ouptut is empty.
FILM.FILM_TITLE = :pfilm
Has nayone any thoughts on why it would fail on something that uses the same method ? is it a case that the value isn't bieng passed across? I'm a little stumped if that's the case as I set it up the same way as the working one.
Thanks for looking
I assume from the sound of it you are using application express? Have you turned on debugging to see exactly what is being passed? It might be encoding the spaces or something.
It seems strange that the two, seemingly similar queries would behave differently. Do you have access to the actual sql produced? If so, i would try running that against your db direct through the command line or sql developer if you have it.
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.
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.
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.
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'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.
I've got a particular SQL statement which takes about 30 seconds to perform, and I'm wondering if anyone can see a problem with it, or where I need additional indexing.
The code is on a subform in Access, which shows results dependent on the content of five fields in the master form. There are nearly 5000 records in the table that's being queried. The Access project is stored and run from a terminal server session on the actual SQL server, so I don't think it's a network issue, and there's another form which is very similar that uses the same type of querying...
Thanks
PG
SELECT TabDrawer.DrawerName, TabDrawer.DrawerSortCode, TabDrawer.DrawerAccountNo, TabDrawer.DrawerPostCode, QryAllTransactons.TPCChequeNumber, tabdrawer.drawerref
FROM TabDrawer LEFT JOIN QryAllTransactons ON TabDrawer.DrawerRef=QryAllTransactons.tpcdrawer
WHERE (Forms!FrmSearchCompany!SearchName Is Null
Or [drawername] Like Forms!FrmSearchCompany!SearchName & "*")
And (Forms!FrmSearchCompany.SearchPostcode Is Null
Or [Drawerpostcode] Like Forms!FrmSearchCompany!Searchpostcode & "*")
And (Forms!FrmSearchCompany!SearchSortCode Is Null
Or [drawersortcode] Like Forms!FrmSearchCompany!Searchsortcode & "*")
And (Forms!FrmSearchCompany!Searchaccount Is Null
Or [draweraccountno] Like Forms!FrmSearchCompany!Searchaccount & "*")
And (Forms!FrmSearchCompany!Searchcheque Is Null
Or [tpcchequenumber] Like Forms!FrmSearchCompany!Searchcheque & "*");
");
EDIT
The Hold up seems to be in the union query that forms the QryAllTransactons query.
SELECT
"TPC" AS Type,
TabTPC.TPCRef,
TabTPC.TPCBranch,
TabTPC.TPCDate,
TabTPC.TPCChequeNumber,
TabTPC.TPCChequeValue,
TabTPC.TPCFee,
TabTPC.TPCAction,
TabTPC.TPCMember,
tabtpc.tpcdrawer,
TabTPC.TPCUser,
TabTPC.TPCDiscount,
tabcustomers.*
FROM
TabTPC
INNER JOIN TabCustomers ON TabTPC.TPCMember = TabCustomers.CustomerID
UNION ALL
SELECT
"CTP" AS Type,
TabCTP.CTPRef,
TabCTP.CTPBranch,
TabCTP.CTPDate,
TabCTP.CTPChequeNumb,
TabCTP.CTPAmount,
TabCTP.CTPFee,
TabCTP.CTPAction,
TabCTP.CTPMember,
0 as CTPXXX,
TabCTP.CTPUser,
TabCTP.CTPDiscount,
TABCUSTOMERS.*
FROM
TabCTP
INNER JOIN TabCustomers ON Tabctp.ctpMember = TabCustomers.CustomerID;
I've done a fair bit of work with simple union queries, but never had this before...
Two things. Since this is an Access database with a SQL Server backend, you may find a considerable speed improvement by converting this to a stored proc.
Second, do you really need to return all those fields, especially in the tabCustomers table? Never return more fields than you actually intend to use and you will improve performance.
At first, try compacting and repairing the .mdb file.
Then, simplify your WHERE clause:
WHERE
[drawername] Like Nz(Forms!FrmSearchCompany!SearchName, "") & "*"
And
[Drawerpostcode] Like Nz(Forms!FrmSearchCompany!Searchpostcode, "") & "*"
And
[drawersortcode] Like Nz(Forms!FrmSearchCompany!Searchsortcode, "") & "*"
And
[draweraccountno] Like Nz(Forms!FrmSearchCompany!Searchaccount, "") & "*"
And
[tpcchequenumber] Like Nz(Forms!FrmSearchCompany!Searchcheque, "") & "*"
Does it still run slowly?
EDIT
As it turned out, the question was not clear in that it is an up-sized Access Database with an SQL Server back end-and an Access Project front-end.
This sheds a different light on the whole problem.
Can you explain in more detail how this whole query is intended to be used?
If you use it to populate the RecordSource of some Form or Report, I think you will be able to refactor the whole thing like this:
make a view on the SQL server that returns the right data
query that view with a SQL server syntax, not with Access syntax
let the server sort it out
How many rows are in QryAllTransactons?
If your result returns 0 rows then Access may be able to see that immediately and stop, but if it returns even a single row then it needs to pull in the entire resultset of QryAllTransactons so that it can do the join internally. That would be my first guess as to what is happening.
Your best bet it usually to do joins on SQL Server. Try creating a view that does the LEFT OUTER JOIN and query against that.
Your goal, even when Access is running on the SQL Server itself and minimizes network traffic, is to only send to Access what it absolutely needs. Otherwise a large table will still take up memory, etc.
Have you tried running each of the subqueries in the union? Usually optimizers don't spend much time trying to inspect efficiencies between union elements - each one runs on its own merits.
Given that fact, you could also put the "IF" logic into the procedural code and run each of the tests in some likely order of discovery, without significant additional overhead from more calls.
Get rid of those like operators.
In your case you don't need them. Just check if the field starts with a given value which you can achive whith something like this:
Left([field], Len(value)) = value
This method applied to your query would look like this (did some reformatting for better readability):
SELECT
TabDrawer.DrawerName,
TabDrawer.DrawerSortCode,
TabDrawer.DrawerAccountNo,
TabDrawer.DrawerPostCode,
QryAllTransactons.TPCChequeNumber,
TabDrawer.DrawerRef
FROM
TabDrawer
LEFT JOIN QryAllTransactons
ON TabDrawer.DrawerRef = QryAllTransactons.TpcDrawer
WHERE
(Forms!FrmSearchCompany!SearchName Is Null
Or Left([drawername], Len(Forms!FrmSearchCompany!SearchName)) = Forms!FrmSearchCompany!SearchName)
And
(Forms!FrmSearchCompany.SearchPostcode Is Null
Or Left([Drawerpostcode], Len(Forms!FrmSearchCompany!Searchpostcode)) = Forms!FrmSearchCompany!Searchpostcode)
And
(Forms!FrmSearchCompany!SearchSortCode Is Null
Or Left([drawersortcode], Len(Forms!FrmSearchCompany!Searchsortcode)) = Forms!FrmSearchCompany!Searchsortcode)
And
(Forms!FrmSearchCompany!Searchaccount Is Null
Or Left([draweraccountno], Len(Forms!FrmSearchCompany!Searchaccount)) = Forms!FrmSearchCompany!Searchaccount)
And
(Forms!FrmSearchCompany!Searchcheque Is Null
Or Left([tpcchequenumber], Len(Forms!FrmSearchCompany!Searchcheque)) = Forms!FrmSearchCompany!Searchcheque)
Note that you're comparing case sensitive. I'm not totally sure if the like operator in MS-Access is case insensitive. Convert both strings to upper- or lowercase, if needed.
When you upsized did you make sure the tables were properly indexed? Indexes will speed queries tremendously if used properly (note they may also slow down inserts/updates/deletes, so choose carefully what to index)