How to use multiple inner joins for visual basic 6 - vb6

I am looking for a way to use 2 inner joins so I can link 3 databases together.
I currently use this :
rs.Open "select * from School inner join Name on School.ID = Name.ID", db, 3, 3
I need to add the database called Opdracht. After the DB are linked I want to link all the IDs together. Like in the code above but then 3 IDs.
I hope you can help me with this.

The specific syntax will depend on the database / driver you are using but you simply add another JOIN statement. I prefer building a string and assigning the string as it makes the code easier to read.
...
Dim strSQL as String
strSQL = "SELECT * FROM (School " & _
"INNER JOIN Name ON School.ID = Name.ID) " & _
"INNER JOIN Opdracht ON Opdracht.ID = Name.ID"
rs.Open strSQL, db, 3, 3
...

Related

Trying to display 2 tables

I tried to display 2 tables using this code but it only display the table two, I am really not sure why does it not display table two here is my piece of code.
sub ExecQry
parent.frames(1).DataForm.Query.value = "SELECT * FROM Table1 WHERE Something = " &some.value
parent.frames(1).DataForm.Query.value = "SELECT * FROM Table2 WHERE something = " &some.value
parent.frames(1).DataForm.submit
end sub
becouse you override the table one try useing this
sub ExecQry
parent.frames(1).DataForm.Query.value = "SELECT * FROM Table1,Table2 WHERE
Something = " &some.value
parent.frames(1).DataForm.submit
end sub
I used Joins to work arround on it

Jet Database and pass-through queries, parameters

I'm connecting to a Jet 4 DB through ODBC.
The Jet DB uses pass-through queries to an Oracle DB. This works so far (can't access the p-t queries directly, but creating a view on the query does the trick).
I need some subset of the data returned by the p-ts. Parameters would be best, but are not supported.
Two questions:
1) Jet does seem to be able to push some where-clauses to Oracle. Eg I have a passthrough query that returns 100k rows. A view on the p-t with a single flitering clause (eg "district = '1010'") is very fast, so the processing seems to happen on Oracle. Adding more clauses can slow the query down to a crawl, looping for minutes with high CPU utilization. Is there any documentation on what is passed on and what is done on in the Jet side?
2) There are lots of tutorials on how to create dynamic passthrough queries with VBA/Access. Is it possible to do this (or anything to that effect) with Jet accessed through ODBC?
Thanks
Martin
Edit:
Sorry for being so unclear.
I have a reporting tool that accesses a Jet db through ODBC. The Jet db contains some data and several passthrough queries to an Oracle db. A typical use case would be a generating report for a given department and a given date, using data from Jet and Oracle. This works very well in principle.
The problem is that passthrough queries cannot contain any parameters. A passthrough query works like a view, so I can simply execute "select * from pt_query where dep = 'a' and date = somedate". Jet, however, loads all rows from the pt and does a full scan on the client side. This is unusably slow for a 100k-rows view and I need to find a way to avoid that.
For some simple selects, Jet does seem to let Oracle do the hard work and does not load all rows, hence my question 1.
If that doesn't work, I need to find a way to force Jet to load only the data I need from Oracle for a given request.
I know that I can modify pts through Access VBA, but I only connect through ODBC, so I can only pass SQL to Jet, not call the vb api (unless its possible to inline VB in the SQL statement).
It is not impossible that the query is constructed to cause a table scan, and this is causing the problem.
You seem to be working in VBA. It is possible to construct quite a few interesting queries as SQL strings in VBA and save them to new queries, update existing queries, use them for record sources for forms, or open recordsets. You can use DAO or ADO, depending on what you want to do. I have Oracle, so all I can do is suggest ideas using SQL Server, the connection in square brackets can be got by looking at the connection of a linked table (CurrentDb.TableDefs("NameOfTable").Connect):
Dim cn As New ADODB.Connection
''You can use Microsoft.ACE.OLEDB.12.0 or Microsoft.Jet.OLEDB.4.0
scn = "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" _
& CurrentProject.FullName
cn.Open scn
''An insert query, but you can see that is would be easy enough to
''select from two different databases
s = "INSERT into [ODBC;Description=TEST;DRIVER=SQL Server;" _
& "SERVER=ServerName\SQLEXPRESS;Trusted_Connection=Yes;" _
& "DATABASE=test].Table2 (id, atext) select id, atext from table1"
cn.Execute s
Or
''http://www.carlprothman.net/Default.aspx?tabid=87
strConnect = _
"Provider=sqloledb;" & _
"Data Source=myServerName;" & _
"Initial Catalog=Test;" & _
"Integrated Security=SSPI"
With cmd
.ActiveConnection = strConnect
.CommandType = adCmdText
.CommandText = "SELECT ID, aText FROM table2 " _
& "WHERE ID=?"
.Parameters.Append .CreateParameter _
("ID", adInteger, adParamInput, , 1)
.CommandTimeout = 0
Set rs = .Execute
End With
Can you duplicate the PT query in your own db instead of linking to it in another db?
All the sql in the PT query should get executed on the linked server without Jet attempting to parse or execute it. It's in a foreign language from Jet's point of view.
I'll use code like this in the PT:
SELECT * FROM DHSVIEWS.ClaimHeaderV WHERE
DHSViews.claimheaderV.ClaimType = 'p' AND
DHSViews.claimheaderV.FinalVersionInd = 'y' AND
DHSViews.claimheaderV.ReimbursementAmount > 0 AND
DHSViews.claimheaderV.majorProgram = 'HH' AND
DHSViews.claimheaderV.ServiceDateFrom >= [qStart] AND
DHSViews.claimheaderV.ServiceDateFrom <= [qEnd];
and this in VBA:
Set qdef = db.QueryDefs(qryPT)
sqlOld = qdef.sql
iPosStart = InStr(sqlOld, "[")
sqlNew = sqlOld
Do While iPosStart > 0
iPosEnd = InStr(iPosStart, sqlNew, "]")
param = Mid(sqlNew, iPosStart + 1, iPosEnd - iPosStart - 1)
Select Case param
Case "qStart"
paramVal = "'" & rsQuarter("quarterStart") & "'"
Case "qEnd"
paramVal = "'" & rsQuarter("quarterEnd") & "'"
End Select
sqlNew = Mid(sqlNew, 1, iPosStart - 1) & paramVal & Mid(sqlNew, iPosEnd + 1)
iPosStart = InStr(iPosEnd, sqlNew, "[")
Loop
If sqlNew <> sqlOld Then
qdef.sql = sqlNew
End If
db.QueryDefs(rsPTAppend("append")).Execute
If sqlNew <> sqlOld Then
qdef.sql = sqlOld
End If

Linq Compiled Queries and int[] as parameter

I'm using the following LINQ to SQL compiled query.
private static Func<MyDataContext, int[], int> MainSearchQuery =
CompiledQuery.Compile((MyDataContext db, int[] online ) =>
(from u in db.Users where online.Contains(u.username)
select u));
I know it is not possible to use sequence input paramter for a compiled query and im getting “Parameters cannot be sequences” error when running it.
On another post here related , I saw that there is some solution but I couldn't understand it.
Does anyone know to use complied query with array as input paramter?
Please post example if you do.
Like the post that you referenced, it's not really possible out of the box. The post also references creating your own query provider, but it's a bit of overhead and complexity that you probably don't need.
You have a few options here:
Don't use a compiled query. Rather, have a method which will create a where clause from each item in the array resulting in something like this (psuedo-code):
where
online[0] == u.username ||
online[1] == u.username ||
...
online[n] == u.username
Note that you would have to use expression here to create each OR clause.
If you are using SQL Server 2008, create a scalar valued function which will take a table-valued parameter and a value to compare againt. It will return a bit (to indicate if the item is in the values in the table). Then expose that function through LINQ-to-SQL on your data context. From there, you should be able to create a CompiledQuery for that. Note that in this case, you should take an IEnumerable<string> (assuming username is of type string) instead of an array, just because you might have more than one way of representing a sequence of strings, and to SQL server for this operation, it won't matter what the order is.
One solution that I have found myself doing (for MS SQL 2005/2008). And I'm not sure if it is appropriate in all scenarios is to just write dynamic sql and execute it against the datacontext using the ExecuteQuery method.
For example, if I have an unbounded list that I am trying to pass to a query to do a contains...
' Mock a list of values
Dim ids as New List(of Integer)
ids.Add(1)
ids.Add(2)
' ....
ids.Add(1234)
Dim indivs = (From c In context.Individuals _
Where ids.Contains(c.Id) _
Select c).ToList
I would modify this query to create a SQL string to execute against the database directly like so...
Dim str As New Text.StringBuilder("")
Dim declareStmt as string = "declare #ids table (indivId int) " & vbcrlf)
For i As Integer = 0 To ids.Count - 1
str.Append("select " & ids(i).ToString() & " & vbcrlf)
If i < ids.Count Then
str.Append("union " & vbcrlf)
End If
Next
Dim selStatement As String = "select * From " & context.Mapping.GetTable(GetType(Individuals)).TableName & _
" indiv " & vbcrlf & _
" inner join #ids ids on indiv.id = ids.id"
Dim query = declareStmt & str.ToString & selStatement
Dim result = context.ExecuteQuery(of Individual)(query).ToList
So barring any syntax errors or bugs that I coded (the above is more or less psuedo code and not tested), the above will generate a table variable in SQL and execute an inner join against the desired table (Individuals in this example) and avoid the use of a "IN" statement.
Hope that helps someone out!

Need help with designing a query in ELinq

This is my query:
Dim vendorId = 1, categoryId = 1
Dim styles = From style In My.Context.Styles.Include("Vendor") _
Where style.Vendor.VendorId = vendorId _
AndAlso (From si In style.StyleItems _
Where si.Item.Group.Category.CategoryId = _
categoryId).Count > 0 _
Distinct
I have the feeling that I can improve the performance, cuz the above query is (correct me if I am wrong) performs 2 round-trips to the server; 1 time by the Count and then when it's executed.
I want to send this Count thing to the DB so it should be only one round trip to the server.
Even it's not the exact thing, this is actually what I need:
SELECT DISTINCT Style.*
FROM Style INNER JOIN
Vendor ON Style.VendorId = Vendor.VendorId INNER JOIN
StyleItem ON Style.StyleId = StyleItem.StyleId INNER JOIN
Item ON StyleItem.ItemId = Item.ItemId INNER JOIN
[Group] ON Item.GroupId = [Group].GroupId INNER JOIN
Category ON [Group].CategoryId = Category.CategoryId
WHERE (Style.VendorId = #vendorid) AND (Category.CategoryId = #CategoryId)
I wish I could use this SPROC (i.e. function import etc.), but I need to Include("Vendor"), which constraints me to do it with Linq.
Any kind of suggestion will be really welcommed!
It is probably not doing two trips to the database. It will get optimized before it is executed, and nothing gets executed until you try the read the data.
Normally I check the SQL that is created using SQL Profiler. I have also found LinqPad to be very usefull.

How to combine 2 LINQ into one

I am trying to populate a treeview control with some info and for that I am using 2 separate LINQ statements as follows;
Dim a = From i In CustomerTable _
Group By ShipToCustName = i.Item(6), BillToCustName = i.Item(4) Into Details = Group, Count() _
Order By ShipToCustName
Dim b = From x In a _
Group By ShipToName = x.ShipToCustName Into Group, Count() _
Order By ShipToName
For Each item In b
Console.WriteLine("Shitp To Location: " + item.ShipToName)
For Each x In item.Group
Console.WriteLine("...BillTo:" + x.BillToCustName)
For Each ticket In x.Details
Console.WriteLine("......TicketNum" + ticket.Item(0).ToString)
Next
Next
Next
Is there a way to combine A and B into one query ? Any help please ...
Well, really B is a single query. Remember that what comes back from a Linq statement is an IQueryable, not the actual result. This means that B combines its own expressions with that of A, but retrieval is not performed until you enumerate B. So B really is just a single query.

Resources