here is the connection i have
strCon="DBQ=" & Server.Mappath("db.mdb") & ";Driver={Microsoft Access Driver (*.mdb)};PWD=password;"
set adoCon=server.createobject("adodb.connection")
adoCon.Open strCon
so in order to work with the 2 databases i have 2 adoCon and when i do the select i select from each db i need
now for the problem...
in this situation i will be able only to get all the info from one and then from the other one. but what i want is to be able to put the together.
db1.tblcats has categories and db2.tblcats has categories and subcategories
so in addition to be able to select both of the together, i need to be able to know what cat is from what db
Step 2 after the big help
this is my code
strSQL = "SELECT name FROM tblcats union " _
& "select name from [MS Access;PWD=pass;DATABASE=" & Server.Mappath("../shop.mdb") & "].tblcats as bcats where bcats.father=50"
rs.CursorType = 3
rs.LockType = 3
rs.Open strSQL, strCon
while not rs.eof
response.write rs("name")&"<br>"
rs.movenext
wend
how can i know what record came from what db? cause i need to act difrently for each one
You can use IN:
SELECT t1.*, t2.*
FROM T1
INNER JOIN
(SELECT * FROM atable
IN 'C:\Docs\DB2.mdb') t2
ON t1.ID=t2.ID
EDIT:
sc = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\docs\other.mdb"
cn.open sc
s="SELECT * FROM t1 INNER JOIN " _
& "[MS Access;PWD=databasePWD;DATABASE=C:\docs\db.mdb].t2 ON t1.ID=t2.ID"
rs.Open s, cn
EDIT 2:
You can use the aliases to identify which database a field is from:
s="SELECT * FROM table1 t INNER JOIN " _
& "[MS Access;PWD=databasePWD;DATABASE=C:\docs\db.mdb].m ON t.ID=m.ID"
msgbox rs.fields("m.code") & " " & rs.fields("t.code")
EDIT 3
Or you can add a virtual field:
SELECT 1 AS "DB", Field, Field FROM ...
UNION ALL
SELECT 2 AS "DB", Field, Field FROM
UNION ALL is usually faster.
Related
I have a single table in Access 2010:
TMP [CUST,ITEM,START_PD]
I want to get the END_PD for each CUST / ITEM.
END_PD being defined as the period before the next higher START_PD for the same CUST / ITEM.
So I perform a left join of the table to itself, using an inequality operator on START_PD as below.
SELECT s.CUST, s.ITEM, s.START_PD, Min(e.START_PD-1) AS END_PD
FROM TMP AS s
LEFT JOIN TMP AS e ON s.CUST=e.CUST AND s.ITEM=e.ITEM AND e.START_PD>s.START_PD
GROUP BY s.CUST, s.ITEM, s.START_PD
ORDER BY s.CUST, s.ITEM, s.START_PD
The base table has 46,556 rows. I would expect the query result to have the same, but the query only returns 14,967 rows.
Even when I try to return all records in the left join, I get far less than the base table. See below:
SELECT s.*,e.*
FROM TMP AS s
LEFT JOIN TMP AS e ON s.ITEM = e.ITEM AND s.CUST = e.CUST AND e.START_PD>s.START_PD
The above query only returns 19,014 records... less than the base table.
This is holding up a major project, and I'd appreciate any help. So far, it's looking like an Access bug. Any workarounds?
EDIT:
I have tried testing a small sample of the data by including WHERE s.CUST='WALMART' AND s.ITEM='0001H'. This fails by excluding the last START_PD, for which there is none greater.
CUST ITEM START_PD END_PD
WALMART 0001HAC 20694 20696
WALMART 0001HAC 20697 20704
WALMART 0001HAC 20705 20706
Strangely, if I select that same sample of the data (WALMART/0001H) into a separate table and run the EXACT SAME query on that smaller table (changing only the table name), it works fine as below. That is why I tend to think this is a bug.
CUST ITEM START_PD END_PD
WALMART 0001HAC 20694 20696
WALMART 0001HAC 20697 20704
WALMART 0001HAC 20705 20706
WALMART 0001HAC 20707
To answer my own question, I'd like to:
Demonstrate that this is a bug
Provide a workaround
Proof that this is a bug.
Sub Test()
Dim db As DAO.Database, rst As DAO.Recordset
Set db = CurrentDb
On Error Resume Next
db.QueryDefs.Delete "TMP_EXTENDED"
db.QueryDefs.Delete "RAW_LEFT_JOIN"
db.TableDefs.Delete "TMP"
On Error GoTo 0
'Table definition.
strSql = _
"CREATE TABLE TMP ( " & vbCrLf & _
" CUST VARCHAR(10), " & vbCrLf & _
" ITEM VARCHAR(10), " & vbCrLf & _
" START_PD LONG, " & vbCrLf & _
" PRIMARY KEY (CUST,ITEM,START_PD) " & vbCrLf & _
");"
db.Execute strSql, dbFailOnError
'Populate with data.
Set rst = db.OpenRecordset("TMP")
For custNo = 1 To 25 'change to affect final row count
For itemNo = 1 To 100 'change to affect final row count
For pdNo = 1 To 3 'change to affect final row count
strCust = "CUST" & custNo
strItem = "ITEM" & itemNo
rst.AddNew
rst("CUST") = strCust
rst("ITEM") = strItem
rst("START_PD") = pdNo
rst.Update
If rst.RecordCount Mod 1000 = 0 Then Debug.Print rst.RecordCount 'just to monitor.
Next
Next
Next
Debug.Print "TMP Table Row Count is: " & DCount("*", "TMP")
'Test query to find end period for each CUST/ITEM/START_PD.
Dim qdf As New QueryDef
qdf.Name = "TMP_EXTENDED"
qdf.SQL = "SELECT s.CUST, s.ITEM, s.START_PD, Min(e.START_PD-1) AS END_PD " & vbCrLf & _
"FROM TMP AS s " & vbCrLf & _
"LEFT JOIN TMP AS e ON (s.CUST=e.CUST AND s.ITEM=e.ITEM AND e.START_PD>s.START_PD) " & vbCrLf & _
"GROUP BY s.CUST, s.ITEM, s.START_PD " & vbCrLf & _
"ORDER BY s.CUST, s.ITEM, s.START_PD"
db.QueryDefs.Append qdf
Debug.Print "TMP_EXTENDED Row Count is: " & DCount("*", "TMP_EXTENDED")
'Test query to just perform the left join.
Set qdf = New QueryDef
qdf.Name = "RAW_LEFT_JOIN"
qdf.SQL = "SELECT s.*,e.* " & vbCrLf & _
"FROM TMP AS s " & vbCrLf & _
"LEFT JOIN TMP AS e ON s.ITEM = e.ITEM AND s.CUST = e.CUST AND e.START_PD>s.START_PD"
db.QueryDefs.Append qdf
Debug.Print "RAW_LEFT_JOIN Row Count is: " & DCount("*", "RAW_LEFT_JOIN")
RefreshDatabaseWindow
End Sub
When run as written, the above code returns:
TMP Table Row Count is: 7500
TMP_EXTENDED Row Count is: 5000
RAW_LEFT_JOIN Row Count is: 7500
Obviously this is wrong because a left join should always return all the records in the left table. In this case, TMP_EXTENDED should have returned 7500, and RAW_LEFT_JOIN should have returned more than 7500.
The loop bounds for custNo, itemNo, and pdNo can be changed to adjust the record count in table TMP. If you do this, you will see that the query works until the record count reaches about 7000, then it fails.
The same problem does not appear to exist when the join is only performed on one 'entity' column. For example, I modified the above code to use a table with only a CUST column and START_PD column, and got both queries to work properly on a table record count of 600,000.
Workaround
Since posting this, I have found another quite similar post in which a decent workaround is presented. I have modified it as below. I do not know HOW reliable it is going to be, but I'm going with it for now.
SELECT s.CUST, s.ITEM, s.START_PD, Min(e.START_PD) AS END_PD
FROM TMP AS s INNER JOIN TMP AS e ON s.ITEM = e.ITEM AND s.CUST = e.CUST
WHERE e.START_PD>s.START_PD
GROUP BY s.CUST, s.ITEM, s.START_PD
UNION ALL
SELECT CUST, ITEM, Max(START_PD), Null
FROM TMP
GROUP BY CUST, ITEM, Null
ORDER BY CUST,ITEM,START_PD,END_PD
Any "atypical" (not only table1.field = table2.field, but anything with constants, calculations, or comparison operators other than equality) join in Access should have it's ON clause surrounded by braces:
SELECT s.*,e.*
FROM TMP AS s
LEFT JOIN TMP AS e ON (s.ITEM = e.ITEM AND s.CUST = e.CUST AND e.START_PD>s.START_PD)
However, usually, these kinds of joins return a Join expression not supported error instead of giving incorrect results. I don't know why this one doesn't.
I am fairly new to the world of programming and am self-taught. From everything I've read I think I need code that includes the use of sub-queries. However, I've never created any sub-queries so I'm a little lost on how to accomplish that.
I have a table that include multiple tickets entered by different users for specific teams and categories. I need to count the # of tickets per combinations and then pull back a random no of tickets (5 %) based on each combination.
For example the combo of Smith,SamL&CInquiry has 176 tickets, I need to pull 9 of those tickets
The combo of Brown,TomL&CLicensing has 22 tickets, I need to pull 1 of those.
I am attempting to do this in Access database.
Here's what I've tried:
Public Function Test()
Set dbs = CurrentDb
Dim newqry As QueryDef
Set newqry = dbs.CreateQueryDef(rst2) i = 1 i2 = 1
Set rst = dbs.OpenRecordset("Query1", dbOpenDynaset)
Do Until i2 > i
rst.Move Int(Rnd(rst.RecordCount) * 100)
If i2 = 1 Then
query_filter_store = " where combo ='" & rst.combo.Value & "'"
Else
query_filter_store = query_filter_store & " or " & "combo='" & rst.combo.Value & "'"
End If
i2 = i2 + 1
Loop
'Set rst2 = dbs.OpenRecordset("select * from query1" & query_filter_store)
Set rst2 = dbs.CreateQueryDef("test_query", "select * from query1 " & query_filter_store)
I have a button which uses two separate queries that pull data from two tables and insert into another table:
Dim lngID As Long
Dim lngIDCallout As Long
Dim strSQL1 As String
lngID = CalloutAttendance_MultiSelect.Value
lngIDCallout = Forms![Callouts].[CalloutID].Value
strSQL1 = "INSERT INTO Members_Callouts(MemberID) SELECT MemberID FROM Members WHERE MemberID=" & lngID
strSQL2 = "INSERT INTO Members_Callouts(CalloutID) SELECT CalloutID FROM Callouts WHERE CalloutID=" & lngIDCallout
CurrentDb.Execute strSQL1
CurrentDb.Execute strSQL2
CalloutAttendance_MultiSelect.Requery
And whilst it almost does what I want it to do, it inserts the the two values as two separate new records, whereas I'd like it to insert it into ONE new record. I've had a go, but I either get syntax errors, or in the case below, I got a 3067 runtime error "Query input must contain at least one table or query"
strSQL1 = "INSERT INTO Members_Callouts(MemberID, CalloutID) SELECT
(SELECT MemberID FROM Members WHERE MemberID=" & lngID & "),
(SELECT CalloutID FROM Callouts WHERE CalloutID=" & lngIDCallout & ")"
Anyone know where I might be going wrong?
Thanks :-)
In this case you're just inserting the key values so all you need to do is
strSQL1 = _
"INSERT INTO Members_Callouts (MemberID, CalloutID) " & _
"VALUES (" & lngID & ", " & lngIDCallout & ")"
In other words, you don't need to bother with something like...
"(SELECT MemberID FROM Members WHERE MemberID=" & lngID & ")"
...since the value it returns is just lngId (assuming that the value exists in the [Members] table).
INSERT INTO
MyTable (Col1,Col2,Col3,Col4,Col5,Col6,Col7)
SELECT
f1.col1, f2.col2, f3.col3, f3.col4, f3.col5, f4.col6, f5.col7
FROM
(SELECT Col1 FROM Func1()) AS f1
CROSS JOIN
(SELECT Col2 FROM Func2()) AS f2
CROSS JOIN
(SELECT Col3,Col4,Col5 FROM Func3()) AS f3
CROSS JOIN
(SELECT Col6 FROM Func4()) AS f4
CROSS JOIN
(SELECT Col7 FROM Func5()) AS f5
How can i compare two MS ACCESS 2007 databases.Both databases contain same tables with same feilds ad structure.i need to compare the record values between two databases to detect any difference in record values.
ACCESS 2007 Database1
serial no. | NAME | ADDRESS
1 smith street 1
2 john street 4
3 alix street 8
ACCESS 2007 Database2
serial no.| NAME | ADDRESS
1 smith street 1
2 jhn stret 4
3 alix street 8
I need a VBA code for ms access that can detect the differece of records,just as the records at serial number two.
First thing you should do is link in one of the tables to the other database, e.g link the Database 2 table into database one (this allows both to be queried together) then you could use this simple example with concatenation to determine if all the fields strung together match based on the serial number:
SELECT T1.*, T2.*
FROM Table1 As T1, Table2 As T2
WHERE T2.[serial no.] = T1.[serial no.]
AND T2.[NAME] & T2.[ADDRESS] <> T1.[NAME] & T1.[ADDRESS]
You could also specify the columns with each of their own condition if you prefer.
NOTE: This is assuming you are only looking for differences where the serial no matches, if you also need to identify records that may appear in one table but not the other then you will need to use an "Un-matched" query, the query designer can help you with this or post back and I can update my answer.
Option Compare Database
Private Sub Command4_Click()
Dim tablename1, tablename2 As String
tablename1 = Text0.Value
tablename2 = Text2.Value
'On Error GoTo Err_cmdValidateGeneralInfo_Click
Dim F As DAO.Field
Dim rs As DAO.Recordset
Dim rs1 As DAO.Recordset
Set curDB = CurrentDb()
'If Me.DateModified = Date Then
'Adds new employees to the TT_GeneralInfo table in the FTEI_PhoneBook.mdb - which is used thru out the AP databases.
' DoCmd.OpenQuery "qryEmpData_TT_General"
strsql = "Select * from " & tablename1
Set rs = curDB.OpenRecordset(strsql)
strsql1 = "Select * from " & tablename2
DoCmd.CopyObject , "Unmatched_records", acTable, tablename1
curDB.Execute "DELETE FROM Unmatched_records"
Set rs1 = curDB.OpenRecordset(strsql1)
Do Until rs.EOF
For Each F In rs.Fields
If rs.Fields(F.Name) <> rs1.Fields(F.Name) Then
'rs.Edit
strsql = "Select * into test from " & tablename1 & " where " & F.Name & " = """ & rs.Fields(F.Name) & """"
DoCmd.RunSQL strsql
If DCount(F.Name, "test") <> 0 Then
GoTo append_unmatch
'appending unmacthed records
append_unmatch:
strsql2 = "insert into Unmatched_records Select * from test"
DoCmd.RunSQL strsql2
'if record doesnt match move to next one
GoTo Nextrecord
End If
' rs.Fields(F.Name) = rs1.Fields(F.Name)
' rs.Update
End If
Next F
Nextrecord:
rs.MoveNext
rs1.MoveNext
Loop
'To check whether tables matched or not
Dim rs2 As DAO.Recordset
strsql3 = "select * from Unmatched_records"
Set rs2 = curDB.OpenRecordset(strsql3)
For Each F In rs2.Fields
If DCount(F.Name, "Unmatched_records") <> 0 Then
MsgBox ("The two tables didnt match. Check table test for unmatching reocrds.")
Else
MsgBox ("Tables match!")
End If
Exit Sub
Next F
rs2.Close
End Sub
I have a combination field that contains a query.I want to speed up my access forms hence I want to run the query of this combinationfield in runtime( in VB code) but I dont know how? Would you please show me an example?
if you want a SELECT query then use
Dim recSet As Recordset
recSet = CurrentDb.OpenRecordset("SELECT * FROM table1 WHERE field1=" & Me.myField)
or
recSet = DoCmd.RunSQL("SELECT * FROM table1 WHERE field1=" & Me.myField)
for other commands (DELETE, UPDATE, INSERT,...) use
CurrentDb.Execute "DELETE * FROM table1 WHERE field1=" & Me.myField
or
DoCmd.RunSQL "DELETE * FROM table1 WHERE field1=" & Me.myField