Professional Documents
Culture Documents
The ADO Object Model.
The ADO Object Model.
The ADO Object Model.
Dim cn As New ADODB.Connection cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source=C:\Microsoft Visual Studio\Vb98\Biblio.mdb"
Dim cn As New ADODB.Connection cn.Open "Provider=SQLOLEDB;Data Source=MyServer;Initial Catalog=Pubs;" _ & "User ID=sa;Password=;", , , adAsyncConnect
level = cn.BeginTrans
On Error Resume Next value = cn.Properties("Transaction DDL") If Err = 0 Then level = cn.BeginTrans If level = 1 Then MsgBox "A top-level transaction has been initiated" Else MsgBox "A nested transaction has been initiated" End If Else MsgBox "This provider doesn't support transactions" End If
Private Sub cn_WillConnect(ConnectionString As String, UserID As String, _ Password As String, Options As Long, _ adStatus As ADODB.EventStatusEnum, _ ByVal pConnection As ADODB.Connection)
Private Sub cn_ConnectComplete(ByVal pError As ADODB.error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pConnection As ADODB.Connection)
Private Sub cn_WillExecute(Source As String, _ CursorType As ADODB.CursorTypeEnum, LockType As ADODB.LockTypeEnum, _ Options As Long, adStatus As ADODB.EventStatusEnum, _ ByVal pCommand As ADODB.Command, _ ByVal pRecordset As ADODB.Recordset, _ ByVal pConnection As ADODB.Connection)
ADODB.EventStatusEnum, _ ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, _ ByVal pConnection As ADODB.Connection)
Private Sub cn_BeginTransComplete(ByVal TransactionLevel As Long, _ ByVal pError As ADODB.error, adStatus As ADODB.EventStatusEnum, _ ByVal pConnection As ADODB.Connection)
Private Sub cn_CommitTransComplete(ByVal pError As ADODB.error, adStatus _ As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection) Private Sub cn_RollbackTransComplete(ByVal pError As ADODB.error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
Private Sub cn_InfoMessage(ByVal pError As ADODB.error, adStatus As _ ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
10
11
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\NWind.mdb" Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH rs.Source = "Employees" rs.Open , cn
rs.Open "Employees", cn
' Edit this constant to match your directory structure. Const DBPATH = "C:Program Files\Microsoft Visual Studio\VB98\NWind.mdb" ' First method: explicit Connection object cn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH_ Set rs.ActiveConnection = cn rs.Source = "Employees" rs.Open ' Second method: implicit Connection object rs.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source= " & DBPATH rs.Source = "Employees" rs.Open
12
13
14
' Print the names and values of all the fields in the Recordset. Dim i As Integer For i = 0 To rs.Fields.Count _ 1 ' The Fields collection is zero-based. Print rs.Fields(i).Name & " = " & rs.Fields(i).Value Next
15
Dim fld As ADODB.Field For Each fld In rs.Fields Print fld.Name & " = " & fld Next
' Convert the contents of the LastName field to uppercase. rs.MoveFirst Do Until rs.EOF rs("LastName") = UCase$(rs("LastName")) rs.MoveNext Loop
' Count all employees hired before January 1, 1994. rs.MoveFirst Do Until rs.EOF If rs("HireDate") < #1/1/1994# then count = count + 1 rs.MoveNext Loop
16
Dim mark As Variant mark = rs.Bookmark rs.MoveLast rs("HireDate") = #12/10/1994# HireDate field. rs.Bookmark = mark
' Remember where you are. ' Move to the last record. ' Assign a new value to the ' Return to the marked record.
' Print the names of the employees who were hired on the same ' day as (or later than) the employee whose record is current in the Recordset. Dim mark As Double, curHireDate As Date mark = rs.Bookmark: curHireDate = rs("HireDate") rs.MoveFirst Do Until rs.EOF If rs.Bookmark <> mark Then ' Don't consider the current employee. If rs("HireDate") >= curHireDate Then Print rs("LastName") End If rs.MoveNext Loop ' Move the record pointer back to the record that was current. rs.Bookmark = mark
17
Private Sub HScrollBar1_Change() On Error Resume Next rs.AbsolutePosition = HScrollBar1.Value End Sub
' Sort the Recordset on the LastName and FirstName fields. rs.Sort = "LastName, FirstName"
' Sort in descending order on the HireDate field. (The employees hired ' most recently should be listed first.) rs.Sort = "HireDate DESC"
18
' Filter out all employees hired before January 1, 1994. rs.Filter = "HireDate >= #1/1/1994#" ' Include only employees born in the 1960s. rs.Filter = "birthdate >= #1/1/1960# AND birthdate < #1/1/1970#" ' Filter in only employees whose last names start with the letter C. rs.Filter = "LastName LIKE 'C*'"
' Filter out those employees who were hired when they were over age 35. ReDim marks(1 To 100) As Variant Dim count As Long ' Prepare an array of bookmarks. (Assume that 100 bookmarks are enough.) Do Until rs.EOF If Year(rs("HireDate")) - Year(rs("BirthDate")) > 35 Then count = count + 1 marks(count) = rs.Bookmark End If rs.MoveNext Loop ' Enforce the new filter using the array of bookmarks. ReDim Preserve marks(1 To count) As Variant rs.Filter = marks
19
20
21
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\VB98\NWind.mdb" ' All the following examples use these variables. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset Dim connString As String, sql As String connString = "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & DBPATH ' Open the Recordset using an existing Connection object. cn.Open connString rs.Open "Employees", cn, adOpenStatic, adLockReadOnly, adCmdTable ' Open the Recordset using a Connection object created on the fly. ' This creates a forward-only, read-only Recordset. rs.Open "Employees", connString, , , adCmdTable ' After the Recordset has been opened, you can query the properties ' of the implicit Connection object. Print "Current Connection String = " & rs.ActiveConnection.ConnectionString ' Select only the employees who were born in the 1960s or later. sql = "SELECT * FROM Employees WHERE BirthDate >= #1/1/1960#" rs.Open sql, connString, , , adCmdText
22
23
' Print employee's first and last name. Print rs.Fields("FirstName").Value, rs.Fields("LastName").Value
' The first method uses a regular ForNext loop. For i = 0 To rs.Fields.Count _ 1 Print rs.Fields(i).Name & " = " & rs(i) Next ' The second method uses a For EachNext loop. Dim fld As ADODB.Field For Each fld In rs.Fields Print fld.Name & " = " & fld.Value Next
24
Dim values As Variant, fldIndex As Integer, recIndex As Integer values = rs.GetRows(, , Array("LastName", "FirstName", "BirthDate")) For recIndex = 0 To UBound(values, 2) For fldIndex = 0 To UBound(values) Print values(fldIndex, recIndex), Next Print Next
Dim i As Long Open "datafile.txt" For Output As #1 For i = 0 To rs.Fields.Count _ 1 If i > 0 Then Print #1, ";"; Print #1, rs.Fields(i).Name; Next Print #1, "" rs.MoveFirst Print #1, rs.GetString(, , ";", vbCrLf); CR-LF here. Close #1
25
Private Sub cmdFirst_Click() rs.MoveFirst End Sub Private Sub cmdPrevious_Click() If Not rs.BOF Then rs.MovePrevious End Sub Private Sub cmdNext_Click() If Not rs.EOF Then rs.MoveNext End Sub Private Sub cmdLast_Click() rs.MoveLast End Sub
rs.MoveFirst Do Until rs.EOF total = total + rs("UnitsInStock") * rs("UnitPrice") rs.MoveNext Loop Print "Total of UnitsInStock * UnitPrice = " & total
26
rs.Move 0, adBookmarkFirst rs.Move _1 rs.Move 1 rs.Move 0, adBookmarkLast rs.Move 10, adBookmarkFirst rs.Move -1, adBookmarkLast last record. rs.Move 0 record.
' Same as MoveFirst ' Same as MovePrevious ' Same as MoveNext ' Same as MoveLast ' Move to the tenth record. ' Move to the next to the ' Refresh the current
27
' Update four fields in one operation. rs.Update Array("FirstName", "LastName", "BirthDate", "HireDate"), _ Array("John", "Smith", #1/1/1961#, #12/3/1994#)
If rs.EditMode = adEditInProgress Then If MsgBox("Do you want to commit changes?", vbYesNo) = vbYes Then rs.Update Else rs.CancelUpdate End If End If
' This statement has the same effect as the previous code snippet. rs.AddNew Array("FirstName", "LastName", "BirthDate"), _ Array("Robert", "Doe", #2/5/1955#)
rs.Delete [AffectRecords]
28
' After a batch update attempt, delete all the records that failed ' to be transferred to the server. rs.Filter = adFilterConflictingRecords rs.Delete adAffectGroup rs.Filter = adFilterNone ' Remove the filter.
' Search all the employees who were hired after January 1, 1994. rs.MoveFirst rs.Find "HireDate > #1/1/1994#" Do Until rs.EOF Print rs("LastName"), rs("BirthDate"), rs("HireDate") ' Search the next record that meets the criteria, but skip the current one. rs.Find "HireDate > #1/1/1994#", 1
29
Loop
rs.Find "FirstName rs.Find "FirstName rs.Find "FirstName and "Maria". rs.Find "FirstName
' Matches "Joe" and "John". ' Matches "Joe" but not "John". ' Matches "Anne", "Deborah", ' This gives an error: a bug?
UpdateBatch [AffectRecords]
CancelBatch [AffectRecords]
30
' Save a Recordset to a file, and then close both the file ' and the Recordset.
31
rs.Save "C:\datafile.rec", adPersistADTG rs.Close '... ' Reopen the persistent Recordset. rs.Open "C:\datafile.rec", , , , adCmdFile
32
Dim RecordsAffected As Long rs.Open Do If rs Is Nothing Then ' No more Recordsets, so exit. Exit Do ElseIf (rs.State And adStateOpen) = 0 Then ' It was a non-row-returning SQL command. ... Else ' Process the Recordset here. ... End If Set rs.NextRecordset(RecordsAffected) Loop
If rs.Supports(adAddNew Or adDelete Or adFind) Then ' The Recordset supports the AddNew, Delete, and Find methods. End If
33
Private Sub rs_FetchProgress(ByVal Progress As Long, _ ByVal MaxProgress As Long, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
Private Sub rs_FetchComplete(ByVal pError As ADODB.error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) End Sub
Private Sub rs_WillMove(ByVal adReason As ADODB.EventReasonEnum, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
34
Private Sub rs_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.error, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
35
Private Sub rs_WillChangeField(ByVal cFields As Long, _ ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
Private Sub rs_FieldChangeComplete(ByVal cFields As Long, _ ByVal Fields As Variant, ByVal pError As ADODB.error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
Private Sub rs_WillChangeRecord(ByVal adReason As ADODB.EventReasonEnum, _ ByVal cRecords As Long, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
Private Sub rs_RecordChangeComplete( _ ByVal adReason As ADODB.EventReasonEnum, ByVal cRecords As Long, _ ByVal pError As ADODB.error, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
36
Private Sub rs_WillChangeRecordset( _ ByVal adReason As ADODB.EventReasonEnum, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
Private Sub rs_RecordsetChangeComplete( _ ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.error, _ adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
' Full syntax rs.Fields("LastName").Value = "Smith" ' Fields is the Recordset's default property.
37
rs("LastName").Value = "Smith" ' Value is the Field's default property. rs("LastName") = "Smith"
38
39
rs.Fields("BirthDate") = #4/12/1955#
40
Sub FileToBlob(fld As ADODB.Field, FileName As String, _ Optional ChunkSize As Long = 8192) Dim fnum As Integer, bytesLeft As Long, bytes As Long Dim tmp() As Byte ' Raise an error if the field doesn't support GetChunk. If (fld.Attributes And adFldLong) = 0 Then Err.Raise 1001, , "Field doesn't support the GetChunk method." End If ' Open the file; raise an error if the file doesn't exist. If Dir$(FileName) = " " Then Err.Raise 53, ,#"File not found" fnum = FreeFile Open FileName For Binary As fnum ' Read the file in chunks, and append data to the field. bytesLeft = LOF(fnum) Do While bytesLeft bytes = bytesLeft If bytes > ChunkSize Then bytes = ChunkSize ReDim tmp(1 To bytes) As Byte Get #1, , tmp fld.AppendChunk tmp bytesLeft = bytesLeft - bytes Loop Close #fnum End Sub
Sub BlobToFile(fld As ADODB.Field, FileName As String, _ Optional ChunkSize As Long = 8192) Dim fnum As Integer, bytesLeft As Long, bytes As Long Dim tmp() As Byte ' Raise an error if the field doesn't support GetChunk. If (fld.Attributes And adFldLong) = 0 Then
41
Err.Raise 1001, , "Field doesn't support the GetChunk method." End If ' Delete the file if it exists already, and then open a new one for writing. If Dir$(FileName) <> "" Then Kill FileName fnum = FreeFile Open FileName For Binary As fnum ' Read the field's contents, and write the data to the file ' chunk by chunk. bytesLeft = fld.ActualSize Do While bytesLeft bytes = bytesLeft If bytes > ChunkSize Then bytes = ChunkSize tmp = fld.GetChunk(bytes) Put #fnum, , tmp bytesLeft = bytesLeft - bytes Loop Close #fnum End Sub
' Error trapping accounts for values, such as BLOB fields, that ' can't be converted to strings. On Error Resume Next For i = 0 To rs.Fields.Count - 1 lstFields.AddItem rs.Fields(i).Name & " = " & rs.Fields(i).Value Next
42
Function CopyFields(rs As ADODB.Recordset) As ADODB.Recordset Dim newRS As New ADODB.Recordset, fld As ADODB.Field For Each fld In rs.Fields newRS.Fields.Append fld.Name, fld.Type, fld.DefinedSize, _ fld.Attributes Next Set CopyFields = newRS End Function
Function CopyRecordset(rs As ADODB.Recordset) As ADODB.Recordset Dim newRS As New ADODB.Recordset, fld As ADODB.Field Set newRS = CopyFields(rs) newRS.Open ' You must open the Recordset before adding new records. rs.MoveFirst Do Until rs.EOF newRS.AddNew ' Add a new record. For Each fld In rs.Fields ' Copy all fields' values. newRS(fld.Name) = fld.Value ' Assumes no BLOB fields Next rs.MoveNext Loop Set CopyRecordset = newRS End Function
43
Dim cmd As New ADODB.Command cmd.CommandText = "SELECT * FROM Employees WHERE BirthDate > #1/1/1960"
Dim cmd As New ADODB.Command cmd.CommandText = "SELECT * FROM Employees WHERE BirthDate > ? " _ & "AND HireDate > ?"
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual
44
Studio\Vb98\NWind.mdb" ' Create the first Command object. Dim cmd As New ADODB.Command, rs As New ADODB.Recordset cmd.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source= " & DBPATH cmd.CommandText = "SELECT FirstName, LastName FROM Employees" Set rs = cmd.Execute() ' Create a second Command object on the same database connection. Dim cmd2 As New ADODB.Command, rs2 As New ADODB.Recordset Set cmd2.ActiveConnection = cmd.ActiveConnection cmd2.CommandText = "SELECT * FROM Customers" Set rs2 = cmd2.Execute()
45
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\NWind.mdb" Dim cmd As New ADODB.Command, rs As New ADODB.Recordset cmd.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source= " & DBPATH cmd.CommandText = "SELECT * FROM Employees WHERE BirthDate > ? " _ & "AND HireDate > ?" cmd.CommandType = adCmdText ' You can pass multiple parameters without using a temporary array. Set rs = cmd.Execute(, Array(#1/1/1960#, #1/1/1994#))
46
cmd.Parameters.Refresh
47
cmd.Parameters("StartHireDate") = #1/1/1994#
48
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\NWind.mdb" Dim cmd As New ADODB.Command, rs As New ADODB.Recordset cmd.CommandText = "Select * From Employees Where BirthDate > ? " _ & "AND HireDate > ?" cmd.ActiveConnection = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source= " & DBPATH ' You can use a temporary Parameter variable. Dim param As ADODB.Parameter Set param = cmd.CreateParameter("BirthDate", adDate, , , #1/1/1960#) cmd.Parameters.Append param ' Or you can do everything in one operation. cmd.Parameters.Append cmd.CreateParameter("HireDate", adDate, , , _ #1/1/1993#) Set rs = cmd.Execute(, , adCmdText)
' You can reference a parameter by its index in the collection. cmd.Parameters(0) = #1/1/1920# ' But you deliver more readable code if you reference it by its name. cmd.Parameters("HireDate") = #1/1/1920# Set rs = cmd.Execute()
49
Sub ListCustomProperties(obj As Object, lst As ListBox) Dim i As Integer, tmp As String On Error Resume Next lst.Clear For i = 0 To obj.Properties.Count - 1 lst.AddItem obj.Properties(i).Name & " = " & obj.Properties(i) Next End Sub
50
51
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\Biblio.mdb" Dim cn As New ADODB.Connection, cat As New ADOX.Catalog ' Open the connection. cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DBPATH ' Link the catalog to the connection. Set cat.ActiveConnection = cn
' Fill a list box with the names of the stored procedures in the database. Dim proc As ADOX.Procedure For Each proc In cat.Procedures List1.AddItem proc.Name Next
On Error Resume Next ' Not all providers support this capability. owner = cat.GetObjectOwner("Authors", adPermObjTable)
' The next line fails if the database already exists. cat.Create "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;" _ & "Data Source=C:\Microsoft Visual Studio\Vb98\BiblioCopy.mdb"
52
' Add two fields. ' Append the table to ' the collection.
Dim tbl As ADOX.Table, col As ADOX.Column For Each tbl in cat.Tables Print "TABLE " & tbl.Name Print "Created on " & tbl.DateCreated Print "Modified on " & tbl.DateModified Print "Field List ------" For Each col In tbl.Columns Print " " & col.Name Next Next
53
' Add two fields to the Customers table. Dim tbl As ADOX.Table Set tbl = cat.Tables("Customers") tbl.Columns.Append "CustID", adInteger tbl.Columns.Append "Name", adVarChar, 255
Dim tbl As ADOX.Table, ndx As New ADOX.Index ' Create a new index. ndx.Name = "YearBorn_Author" ndx.Unique = True ' Append two columns to it. ndx.Columns.Append "Year Born" ndx.Columns("Year Born").SortOrder = adSortDescending
54
ndx.Columns.Append "Author" ' Add the index to the Authors table. Set tbl = cat.Tables("Authors") tbl.Indexes.Append ndx
' Add a foreign key to the Orders table, and make the key point ' to the EmployeeID field of the Employees table. Dim tbl As ADOX.Table, key As New ADOX.Key Set tbl = cat.Tables("Orders") ' Create the key, and set its attributes. key.Name = "Employee" key.Type = adKeyForeign key.RelatedTable = "Employees" key.UpdateRule = adRICascade ' Add a column to the key, and set its RelatedColumn attribute. key.Columns.Append tbl.Columns("EmployeeId") key.Columns("EmployeeId").RelatedColumn = "EmployeeId" ' Append the key to the table's Keys collection. tbl.Keys.Append key
55
' Edit this constant to match your directory structure. Const DBPATH = "C:\Program Files\Microsoft Visual Studio\Vb98\Biblio.mdb" Dim cn As New ADODB.Connection, cmd As New ADODB.Command ' Note the version number of the Jet OLE DB Provider. cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & DBPATH Set cmd.ActiveConnection = cn cmd.CommandText = "Select * From Authors Where [Year Born] = [Year]" cmd.Parameters.Append cmd.CreateParameter("Year", adInteger, adParamInput) ' Open the Catalog, and create the new procedure. Set cat.ActiveConnection = cn cat.Procedures.Append "AuthorsByYear", cmd
' Displays which permissions on the Customers table ' have been granted to the users in the Guests group. Dim grp As ADOX.Group, permissions As Long Set grp = cat.Groups("Guests") permissions = grp.GetPermissions("Customers", adPermObjTable) If permissions And adRightExecute Then Print "Execute" If permissions And adRightRead Then Print "Read" If permissions And adRightUpdate Then Print "Update" If permissions And adRightInsert Then Print "Insert"
56
adRightDelete Then Print "Delete" adRightReference Then Print "Reference" adRightCreate Then Print "Create" adRightWriteDesign Then Print "Design" adRightWithGrant Then Print "Grant
' Revoke the Guests group the permission to read the Customers table. cat.Users("Guests").SetPermissions "Customers", adPermObjTable, _ adAccessRevoke, adRightRead ' Give the Managers group full permissions on the Employees table. cat.Users("Managers").SetPermissions "Employees", adPermObjTable, _ adAccessSet, adRightFull
57
Dim cn As New ADODB.Connection cn.Open "File Name=C:\Program Files\Common Files\System\ole db" _ & "\Data Links\Biblio.udl"
Dim rs As New ADODB.Recordset rs.Open "Authors", "Provider=MSDASQL.1;User ID=sa;Data Source=Pubs" ' You can omit the name of the provider because it's the default. rs.Open "Authors", "DSN=Pubs"
58
59
' You can omit the Provider argument because you're using MSDASQL. cn.ConnectionString = "DRIVER={SQL Server};SERVER= MyServer;"_&"UID=sa;DATABASE=pubs"
' Prepare to open a read-only connection. Dim cn As New ADODB.Connection cn.ConnectionTimeout = 30 ' Default for this property is 15 seconds. cn.Mode = adModeRead ' Default for this property is adModeUnknown.
cn.ConnectionString = "Provider=SQLOLEDB.1;Data Source=MyServer;" _ & "Initial Catalog=Pubs" ' The second and third arguments are the user name and the password. cn.Open , "sa", "mypwd"
60
Dim rs As New ADODB.Recordset rs.Open "Authors", "Provider=SQLOLEDB.1;Data Source=MyServer;User ID=sa;" _ & "Password=mypwd;Initial Catalog=Pubs"
Dim cmd As New ADODB.Command cmd.ActiveConnection = "Provider=SQLOLEDB.1;Data Source= MyServer;" _&"userID=sa;Password=mypwd;Initial Catalog=Pubs" cmd.CommandText = "DELETE FROM Authors WHERE State = 'WA'" cmd.Execute
' Display the errors in the connection created by the previous example. Dim er As ADODB.Error For Each er In cmd.ActiveConnection.Errors Debug.Print er.Number, er.Description Next
61
' Display the login dialog box if necessary. Dim cn As New ADODB.Connection cn.Properties("Prompt") = adPromptComplete cn.Open "Provider=MSDASQL.1;Data Source=Pubs"
Dim cn As New ADODB.Connection On Error Resume Next cn.Open "Provider=sqloledb;Data Source=MyServer;Initial Catalog=pubs;" _ &"UserID=sa;Password=;", , , adAsyncConnect ' State is a bit-field value, so you need the And operator to test one bit. Do While (cn.State And adStateConnecting) ' Perform your operations here. ... ' Let the user interact with the program's user interface. DoEvents Loop ' Check whether the connection has been successful. If cn.State And adStateOpen Then MsgBox "The connection is
62
open."
Dim WithEvents cn As ADODB.Connection Private Sub cmdConnect_Click() Set cn = New ADODB.Connection cn.ConnectionTimeout = 20 cn.Open "Provider=sqloledb;Data Source=MyServer;" _ & "Initial Catalog=pubs;", "sa", , adAsyncConnect End Sub Private Sub cn_ConnectComplete(ByVal pError As ADODB.Error, adStatus As _ ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection) If adStatus = adStatusOK Then MsgBox "The connection is open" ElseIf adStatus = adStatusErrorsOccurred Then MsgBox "Unable to open the connection" & vbCr & Err.Description End If End Sub
Private Sub cn_WillConnect(ConnectionString As String, UserID As String, _ Password As String, Options As Long, adStatus As _ ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection) If UserID <> "" And Password = "" Then ' Ask for user's password. Password = InputBox("Please enter your password") If Password = "" Then ' If not provided, cancel the command if possible. If adStatus <> adStatusCantDeny Then adStatus = adStatusCancel End If End If End Sub
63
' Select a different source, based on an array of option buttons. Dim rs As New ADODB.Recordset If optSource(0).Value Then ' Database table rs.Source = "Authors" ElseIf optSource(1).Value Then ' Stored procedure rs.Source = "reptq1" ElseIf optSource(2) Then ' SQL query rs.Source = "SELECT * FROM Authors" WHERE au_lname LIKE 'A*'" End If
64
' Method 1: explicit Connection assigned to the ActiveConnection property. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.ConnectionTimeout = 5 cn.Open "Provider=sqloledb;Data Source=P2;Initial Catalog=pubs;", "sa" Set rs.ActiveConnection = cn rs.Open "Authors" ' Method 2: explicit Connection passed to the Open method. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.ConnectionTimeout = 5 cn.Open "Provider=sqloledb;Data Source=P2;Initial Catalog=pubs;", "sa" rs.Open "Authors", cn ' Method 3: implicit Connection created in the Recordset's Open method. ' Note that you need to embed additional connection attributes (such as ' connection timeout and user ID) in the connection string. Dim rs As New ADODB.Recordset rs.Open "Authors", "Provider=sqloledb;Data Source=P2;" _ & "Initial Catalog=pubs;User ID=sa;Connection Timeout=10" ' Method 4: the Execute method of the Connection object. By default, it ' opens a server-side forward-only, read-only Recordset with CacheSize=1. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=sqloledb;Data Source=P2;Initial Catalog=pubs;", "sa" Set rs = cn.Execute("Authors")
' Open a new Recordset on the same connection as "rs". Dim rs2 As New ADODB.Recordset
65
' Select a different source, based on an array of option buttons. If optSource(0).Value Then ' Database table rs.Open "Publishers", , , , adCmdTable Else optSource(1).Value Then ' Stored procedure rs.Open "reptq1", , , , adCmdStoredProc ElseIf optSource(2) Then ' SQL query rs.Open "SELECT * FROM Authors", , , , adCmdText End If
66
' Open a server-side dynamic cursor. ' (Assumes that the ActiveConnection property has been set already.) rs.CursorType = adOpenDynamic rs.Open "SELECT * FROM Authors", , , , adCmdText ' Open a server-side keyset cursor, with a single statement. rs.Open "SELECT * FROM Authors", , adOpenKyset, adLockOptimistic, adCmdText
' Open a client-side static cursor. rs.CursorLocation = adUseClient rs.CursorType = adOpenStatic ' This statement is optional. rs.Open "SELECT * FROM Authors", , , , adCmdText
' This code creates a client-side static cursor. Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=sqloledb;Data Source=P2;" & _ "Initial Catalog=pubs;", "sa" cn.CursorLocation = adUseClient Set rs = cn.Execute("Authors")
67
' Creates a dissociated Recordset with three fields Dim rs As New ADODB.Recordset rs.Fields.Append "FirstName", adChar, 40, adFldIsNullable rs.Fields.Append "LastName", adChar, 40, adFldIsNullable rs.Fields.Append "BirthDate", adDate rs.Open
Dim rs As New ADODB.Recordset Dim lines() As String, fields() As String Dim i As Long, j As Long ' Open the Publishers.dat text file. Open "Publishers.dat" For Input As #1 ' Read the contents of the file, and process each individual line. lines() = Split(Input(LOF(1), 1), vbCrLf) Close #1 ' Process the first line, which contains the list of fields. fields() = Split(lines(0), ";") For j = 0 To UBound(fields) rs.fields.Append fields(j), adChar, 200 Next rs.Open ' Process all the remaining lines. For i = 1 To UBound(lines) rs.AddNew fields() = Split(lines(i), ";") For j = 0 To UBound(fields) rs(j) = fields(j) Next Next ' Display the recordset in the DataGrid control.
68
' Fill a list box with the names of all the authors. Dim rs As New ADODB.Recordset rs.Open "Authors", "Provider=sqloledb;Data Source=P2;" _ & "Initial Catalog=pubs;User ID=sa;Connection Timeout=10" Do Until rs.EOF lstAuthors.AddItem rs("au_fname") & " " & rs("au_lname") rs.MoveNext Loop rs.Close
69
rs.Fields("au_fname").Value
rs("au_fname")
If rs.Supports(adAddNew) Then. . .
rs.AddNew rs.Fields("Name") = "MSPress" rs.Fields("City") = "Seattle" rs.Fields("State") = "WA" If MsgBox("Do you want to confirm?", vbYesNo) = vbYes Then rs.Update Else rs.CancelUpdate End If
70
' Build the FieldNames() variant array. (You need to do this only once.) ReDim fieldNames(0 To fieldMax) As Variant For j = 0 To fieldMax fieldNames(j) = fields(j) Next ' Process the text lines, but use an array of values in AddNew. For i = 1 To UBound(lines) fields() = Split(lines(i), ";") ReDim fieldValues(0 To fieldMax) As Variant For j = 0 To UBound(fields) fieldValues(j) = fields(j) ' Move values into the Variant arrays. Next rs.AddNew fieldNames(), fieldValues() Next
' Increment unit prices of all products by 10%. Do Until rs.EOF rs("UnitPrice") = rs("UnitPrice") * 1.1 rs.MoveNext Loop
If rs.Supports(adUpdate) Then. . .
rs.Delete rs.MoveNext
71
' Update strategy for optimistic locking. On Error Resume Next Do Err.Clear rs.Update If Err = 0 Then Exit Do ElseIf MsgBox("Update command failed:" & vbCr & Err.Description, _ vbRetryCancel + vbCritical) = vbCancel Then Exit Do End If Loop
72
' Ask the end user for a new price for each product that costs more ' than $40. Dim rs As New ADODB.Recordset, cn As New ADODB.Connection Dim newValue As String cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\Program Files\Microsoft Visual Studio\VB98\NWind.mdb" rs.Open "Products", cn Do Until rs.EOF If rs("UnitPrice") > 40 Then ' In a real-world application, you will surely use a better UI. newValue = InputBox("Insert a new price for product " & _ rs("ProductName"), , rs("UnitPrice")) If Len(newValue) Then cn.Execute "UPDATE Products SET UnitPrice=" & newValue & _ " WHERE ProductID =" & rs("ProductID") End If End If rs.MoveNext Loop
' Ask users if they want to selectively delete suppliers from Italy. Dim rs As New ADODB.Recordset, cn As New ADODB.Connection cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" _
73
& "Data Source=E:\Microsoft Visual Studio\VB98\NWind.mdb" rs.Open "Suppliers", cn Do Until rs.EOF If rs("Country") = "Italy" Then If MsgBox("Do you want to delete supplier " & rs("Company Name") _ & "?", vbYesNo) = vbYes Then cn.Execute "DELETE FROM Suppliers WHERE SupplierID =" _ & rs("SupplierID") End If End If rs.MoveNext Loop
cn.Execute "INSERT INTO Employees (LastName, FirstName, BirthDate) " _ & "VALUES ('Smith', 'Robert', '2/12/1953')"
cn.Execute "INSERT INTO Employees (LastName, FirstName, BirthDate) " _ & "VALUES ('" & txtLastName & "', '" & txtFirstName _ & "', '" & txtBirthDate & "')"
' Replace all @n arguments with provided values. Function ReplaceParams(ByVal text As String, ParamArray args() As Variant) Dim i As Integer For i = LBound(args) To UBound(args) text = Replace(text, "@" & Trim$(i + 1), args(i)) Next ReplaceParams = text End Function
74
& "VALUES ('@1', '@2', '@3') cn.Execute ReplaceParams(sql, txtLastName, txtFirstName, txtBirthDate)
Dim rs As New ADODB.Recordset, cn As New ADODB.Connection ' Open the recordset with optimistic batch locking. cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\Microsoft Visual Studio\VB98\NWind.mdb" cn.Open rs.CursorLocation = adUseClient rs.Open "Products", cn, adOpenStatic, adLockBatchOptimistic ' Disconnect the recordset from the data source and free the connection. Set rs.ActiveConnection = Nothing cn.Close Do Until rs.EOF If rs("UnitPrice") > 40 Then ' In a real-world application, you'll surely use a better UI. newValue = InputBox("Insert a new price for product " & _ rs("ProductName"), , rs("UnitPrice")) If Len(newValue) Then rs("UnitPrice") = newValue End If rs.MoveNext Loop ' Ask for confirmation of all changes. If MsgBox("Send updates to the database?", vbYesNo) = vbYes Then ' Reestablish the connection, and send the updates. cn.Open Set rs.ActiveConnection = cn rs.UpdateBatch Else rs.CancelBatch End If
75
' A skeletal code that resolves batch update conflicts On Error Resume Next rs.UpdateBatch rs.Filter = adFilterConflictingRecords If rs.RecordCount > 0 Then ' Resolve the conflicts here. End If ' Go back to the regular recordset. rs.Filter = adFilterNone
76
On Error Resume Next rs.UpdateBatch rs.Filter = adFilterConflictingRecords If rs.RecordCount Then Dim fld As ADODB.Field ' Resync the Recordset to retrieve correct values for UnderlyingValue. rs.Resync adAffectGroup, adResyncUnderlyingValues ' Loop on all the conflicting records. Note that setting the Filter ' property implicitly performs a MoveFirst method. Do Until rs.EOF Print "Conflict on record: " & rs("ProductName") For Each fld In rs.Fields ' Display fields whose local and underlying values don't match. If fld.Value <> fld.UnderlyingValue Then Print "Field: " & fld.Name _ & "- Original value = " & fld.OriginalValue _ & "- Value now in database = " & fld.UnderlyingValue _ & "- Local value = " & fld.Value End If Next rs.MoveNext Loop End If rs.Filter = adFilterNone
77
78
' Prepare the Command object's properties. Dim cmd As New ADODB.Command cmd.CommandText = "UPDATE Publishers SET city = 'London' " _ & "WHERE Pub_ID = '9999'" cmd.CommandTimeout = 10 cmd.CommandType = adCmdText ' This saves ADO some work. ' When you're ready, open the connection and fire the command. Dim cn As New ADODB.Connection Dim recs As Long cn.Open "Provider=sqloledb;Data source=p2;user id=sa;initial catalog=pubs" Set cmd.ActiveConnection = cn cmd.Execute recs Print "RecordsAffected = " & recs
' This code assumes that Command's properties have been set correctly. Dim rs As ADODB.Recordset cmd.CommandText = "SELECT * FROM Publishers WHERE country = 'USA'" Set rs = cmd.Execute ' At this point, the Recordset is already open.
79
rs.Open cmd
Dim cmd As New ADODB.Command, rs As ADODB.Recordset cmd.ActiveConnection = "Provider=sqloledb;Data source=p2;user id=sa;" _ & "initial catalog=pubs" ' Use question marks as placeholders for parameters. cmd.CommandText = "SELECT * FROM Publishers WHERE country = ?" ' You can pass CommandType as the Execute's third argument. Set rs = cmd.Execute(, "USA", adCmdText)
cmd.CommandText = "SELECT * FROM Publishers WHERE country = ? " _ & " AND Pub_Name LIKE ?" ' Note that the LIKE operator follows the SQL Server syntax. Set rs = cmd.Execute(, Array("USA", "N%"), adCmdText)
' Create the collection of parameters. (Do this only once.) With cmd.Parameters .Append cmd.CreateParameter("Country", adChar, adParamInput,
80
20) .Append cmd.CreateParameter("Name", adChar, adParamInput, 20) End With ' Assign a value to parameters. cmd.Parameters("Country") = "USA" cmd.Parameters("Name") = "N%" Set rs = cmd.Execute()
' This code assumes that Data Environment1 has a Connection object named "Pubs" ' and a Command object named ResetSalesReport under it. Dim de As New DataEnvironment1 de.Pubs.Open userid:="sa", Password:="mypwd" de.ResetSalesReport
' You can hardly write code more concise than this! DataEnvironment1.ResetSalesReport
81
' Fill a list box with the names of all supported Commands. ' BEWARE: just referencing the Commands collection opens the connection. Dim cmd As ADODB.Command For Each cmd In DataEnvironment1.Commands List1.AddItem cmd.Name Next
' Fill a list box with authors' names. Dim de As New DataEnvironment1 de.Authors ' Run the query. Do Until de.rsAuthors.EOF List1.AddItem de.rsAuthors("au_fname") & " " & de.rsAuthors("au_lname") de.rsAuthors.MoveNext Loop de.rsAuthors.Close
Dim rs As ADODB.Recordset ' Get a reference to the Recordset, and open it with an optimistic lock. Set rs = DataEnvironment1.rsAuthors rs.Open LockType:=adLockOptimistic Do Until rs.EOF List1.AddItem rs("au_fname") & " " & rs("au_lname") rs.MoveNext Loop rs.Close
82
SELECT au_lname, au_fname, address, city, zip, state FROM authors WHERE (state =?)
DataEnvironment1.AuthorsByState "CA" ' Show the results in a DataGrid control. Set DataGrid1.DataSource = DataEnvironment1.rsAuthorsByState
Dim outParam As Long, retValue As Long retValue = DataEnvironment1.SampleStoredProc(100, outParam) Set DataGrid1.DataSource = DataEnvironment1.rsSampleStoredProc Print "Output parameter = " & outParam Print "Return value = " & retValue
With DataEnvironment1.Commands("SampleStoredProc") ' This is the "royalty" parameter. .Parameters(1) = 100 Set DataGrid1.DataSource = .Execute ' Retrieve the output parameter. Print "Output parameter = " & .Parameters(2) ' The return value is always in Parameters(0). Print "Return value = " & .Parameters(0) End With
Dim recordsAffected As Long With DataEnvironment1.Commands("SampleStoredProc") ' The array of parameters passed to the Execute method must account for ' the return value, which is always the first parameter.
83
Set DataGrid1.DataSource = .Execute(recordsAffected, Array(0, 100)) Print "Output parameter = " & .Parameters(2) Print "Return value = " & .Parameters(0) End With
' Inside the DataEnvironment module Public Property Get StateWanted() As String StateWanted = Commands("AuthorsByState").Parameters("State") End Property Public Property Let StateWanted(ByVal newValue As String) Commands("AuthorsByState").Parameters("State") = newValue End Property
Private m_InfoText As String Public Property Get InfoText() As String InfoText = m_InfoText End Property Public Property Let InfoText(ByVal newValue As String) m_InfoText = newValue End Property ' Add a new text line to the InfoText property. Private Sub Connection1_InfoMessage(ByVal pError As ADODB.Error, _ adStatus As EventStatusEnum, ByVal pConnection As ADODB.Connection) m_InfoText = m_InfoText & "pError = " & pError.Number & " " & _ pError.Description & vbCrLf End Sub
84
Private Sub Form_Load() If (DataEnv1.Connection1.State And adStateOpen) = 0 Then ' In a real application you'll do something smarter ' than just showing a message box. MsgBox "Unable to open the connection", vbCritical End If End Sub
Private Sub Form_Load() If (DataEnv1.Connection1.State And adStateOpen) = 0 Then Dim conn As String conn = "Provider=Microsoft.Jet.OLEDB.3.51;"_ & "Data Source=???" ' ReadDataBasePathFromINI is defined elsewhere. conn = Replace(conn, "???", ReadDataBasePathFromINI()) DataEnv1.Connection1.ConnectionString = conn DataEnv1.Connection1.Open End If End Sub
85
86
ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset) Dim fld As ADODB.Field, i As Integer ' If we can't cancel this event, there's no point in ' validating fields. If adStatus = adStatusCantCancel Then Exit Sub ' Note that we can't use a For Each loop. For i = 0 To UBound(Fields) Set fld = Fields(i) Select Case fld.Name Case "FirstName", "LastName" ' These fields can't be empty strings or Null. If (fld.Value & "") = "" Then adStatus = adStatusCancel Case "GrandTotal" ' This field must be positive. If fld.Value < 0 Then adStatus = adStatusCancel ' Add Case blocks for other fields here. End Select Next End Sub
Private Sub rs_FieldChangeComplete(ByVal cFields As Long, _ ByVal Fields As Variant, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset) If adStatus <> adStatusErrorsOccurred Then ' Update your unbound controls here. End If End Sub
87
' This event will be invoked only once. adStatus = adStatusUnwantedEvent End Sub
Private Sub rs_WillChangeRecord(ByVal adReason As ADODB.EventReasonEnum, _ ByVal cRecords As Long, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) If adReason <> adRsnFirstChange Then ' These two fields can't both be empty strings. If rs("CustAddress") = "" And rs("ShipAddress") = "" Then adStatus = adStatusCancel End If End If End Sub
' Assumes that the form contains two TextBox controls. Private Sub rs_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)
88
' Move data from the Recordset to on-screen controls. txtFirstName.Text = rs("FirstName") txtLastName.Text = rs("LastName") ' Clear the controls' "modified" flag. txtFirstName.DataChanged = False txtLastName.DataChanged = False End Sub
Private Sub rs_WillMove(ByVal adReason As ADODB.EventReasonEnum, _ adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset) ' Move data to Recordset only if user modified the controls' contents. If txtFirstName.DataChanged Then rs("FirstName") = txtFirstName.Text If txtLastName.DataChanged Then rs("LastName") = txtLastName.Text End Sub
89
Dim cn As New ADODB.Connection, recs As Long cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=E:\Microsoft Visual Studio\VB98\Biblio.mdb" cn.Execute "DELETE FROM Publishers WHERE State = 'WA'", _ recs, adAsyncExecute Debug.Print recs & " records affected" ' Displays _1.
90
Private Sub cn_WillExecute(Source As String, _ CursorType As ADODB.CursorTypeEnum, LockType As ADODB.LockTypeEnum, _ Options As Long, adStatus As ADODB.EventStatusEnum, _ ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, _ ByVal pConnection As ADODB.Connection) MsgBox "About to execute command " & Source End Sub
' Put this code inside the WillExecute event. If adStatus <> adStatusCantDeny Then If MsgBox("About to execute statement " & Source & vbCr & "Confirm?", _ vbYesNo + vbInformation) = vbNo Then adStatus = adStatusCancel End If End If
Private Sub cn_ExecuteComplete(ByVal RecordsAffected As Long, _ ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, _ ByVal pConnection As ADODB.Connection) If adStatus = adStatusOK Then MsgBox "Execution of the command has been completed" & vbCr _ & RecordsAffected & " record(s) were affected", vbInformation ElseIf adStatus = adStatusErrorsOccurred Then MsgBox "Execution error: " & pError.Description, vbCritical End If End Sub
91
' In the ExecuteComplete event ' The next statement works with *any* type of command or query. Debug.Print "Statement " & pCommand.CommandText & " has been completed"
92
93
94
Dim cn As New ADODB.Connection, cmd As New ADODB.Command Dim rs As ADODB.Recordset ' Establish the connection. cn.Open "Provider=sqloledb;Data source=p2;user id=sa;initial catalog=pubs" Set cmd.ActiveConnection = cn ' Define the stored procedure. cmd.CommandText = "byroyalty" cmd.CommandType = adCmdStoredProc ' Save ADO some work by creating the parameter yourself. cmd.Parameters.Append cmd.CreateParameter("@percentage", adInteger, _ adParamInput) ' Set a value to this parameter, and execute the query. cmd.Parameters("@percentage") = 100 Set rs = cmd.Execute()
CREATE PROCEDURE byroyalty2 @percentage int, @totalrecs Int Output AS select @totalrecs= count(*) from titleauthor select au_id from titleauthor where titleauthor.royaltyper = @percentage return (@@rowcount)
cmd.CommandText = "byroyalty2" cmd.CommandType = adCmdStoredProc ' Create the Parameters collection With cmd.Parameters .Append cmd.CreateParameter("RETVAL", adInteger, adParamReturnValue) .Append cmd.CreateParameter("@percentage", adInteger, adParamInput) .Append cmd.CreateParameter("@totalrecs", adInteger, adParamOutput) End With
95
' Set a value for input parameters, and run the stored procedure. cmd.Parameters("@percentage") = 100 Set rs = cmd.Execute() ' Dump the contents of the recordset. Do Until rs.EOF Print "Au_ID=" & rs("au_id") rs.MoveNext Loop rs.Close ' Print the values of the output parameter and the return value. Print "Records in titleauthor = " & cmd.Parameters("@totalrecs") Print "Records returned by the query = " & cmd.Parameters("RETVAL")
' This code assumes that all properties have been correctly initialized. Set rs = cmd.Execute() Do Until rs Is Nothing If rs.State = adStateClosed Then Print "---- Closed Recordset Else Do Until rs.EOF For Each fld In rs.Fields Print fld.Name & "="; fld & ", "; Next Print rs.MoveNext Loop Print "---- End of Recordset" End If Set rs = rs.NextRecordset Loop
96
pub_name=New Moon Books pub_name=Binnet & Hardley pub_name=Algodata Infosystems pub_name=Five Lakes Publishing pub_name=Ramona Publishers pub_name=Scootney Books ---- End of Recordset pub_name=Lucerne Publishing ---- End of Recordset pub_name=GGG&G ---- End of Recordset ---- End of Recordset
CREATE PROCEDURE reptq1 AS select pub_id, title_id, price, pubdate from titles where price is NOT NULL order by pub_id COMPUTE avg(price) BY pub_id COMPUTE avg(price)
pub_id=0736, title_id=BU2075, pub_id=0736, title_id=PS2091, pub_id=0736, title_id=PS2106, pub_id=0736, title_id=PS3333, pub_id=0736, title_id=PS7777, ---- End of Recordset avg=9.784, ---- End of Recordset pub_id=0877, title_id=MC2222, pub_id=0877, title_id=MC3021, pub_id=0877, title_id=PS1372, pub_id=0877, title_id=TC3218, pub_id=0877, title_id=TC4203, pub_id=0877, title_id=TC7777,
price=2.99, pubdate=6/30/91, price=10.95, pubdate=6/15/91, price=7, pubdate=10/5/91, price=19.99, pubdate=6/12/91, price=7.99, pubdate=6/12/91,
price=19.99, pubdate=6/9/91, price=2.99, pubdate=6/18/91, price=21.59, pubdate=10/21/91, price=20.95, pubdate=10/21/91, price=11.95, pubdate=6/12/91, price=14.99, pubdate=6/12/91,
97
---- End of Recordset avg=15.41, ---- End of Recordset pub_id=1389, title_id=BU1032, pub_id=1389, title_id=BU1111, pub_id=1389, title_id=BU7832, pub_id=1389, title_id=PC1035, pub_id=1389, title_id=PC8888, ---- End of Recordset avg=18.976, ---- End of Recordset avg=14.7662, ---- End of Recordset
price=19.99, pubdate=6/12/91, price=11.95, pubdate=6/9/91, price=19.99, pubdate=6/22/91, price=22.95, pubdate=6/30/91, price=20, pubdate=6/12/94,
Dim cn As New ADODB.Connection, rs As ADODB.Recordset ' We can reasonably assume that 100 Recordset items will suffice. Dim recs(100) As ADODB.Recordset, recCount As Integer ' Open the connection, and retrieve the first Recordset. cn.Open "Provider=sqloledb;Data source=p2;user id=sa;" _ & "initial catalog=pubs" Set rs = New ADODB.Recordset rs.Open "PubsByCountry", cn ' Retrieve all Recordsets, and clone them. Do recCount = recCount + 1 Set recs(recCount) = rs.Clone Set rs = rs.NextRecordset Loop Until rs Is Nothing ' Now the recs() array contains one clone for each Recordset.
98
Dim cn As New ADODB.Connection cn.Open "Provider=MSDataShape.1;Data Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source= " & DBPATH
SHAPE {parent_command} [[AS] table-alias] APPEND {child_command} [[AS] table-alias] RELATE(parent_column TO child_column) [[AS] table-alias]
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=MSDataShape.1;Data Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\Microsoft Visual Studio\vb98\biblio.mdb" Set rs.ActiveConnection = cn
99
rs.Open "SHAPE {SELECT * FROM Publishers} " _ & "APPEND ({SELECT * FROM Titles} " _ & "RELATE PubID TO PubID) AS Titles"
Set MSHFlexGrid1.DataSource = rs
SHAPE {SELECT * FROM Authors} AS [Authors With Titles] APPEND (( SHAPE {SELECT * FROM [Title Author]} APPEND ({SELECT * FROM Titles} RELATE ISBN TO ISBN) AS Titles1) RELATE Au_ID TO Au_ID) AS Title_Author
SHAPE {SELECT * FROM Authors} APPEND (( SHAPE {SELECT * FROM [Title Author]} APPEND ({SELECT * FROM Titles} RELATE ISBN TO ISBN) AS Titles1) AS Title_Author RELATE Au_ID TO Au_ID) AS Title_Author, ({SELECT * FROM Authors} RELATE [Year Born] TO [Year Born]) AS AuthorsBornSameYear
100
' You can enclose field and table names within ' single quotes or square brackets. rs.Open "SHAPE {SELECT * FROM Titles} AS Titles " _ & "COMPUTE Titles BY 'Year Published'"
' Group titles by publishers and year of publication. rs.Open "SHAPE {SELECT * FROM Titles} AS Titles " _ & "COMPUTE Titles BY PubID, 'Year Published'"
' Group titles by publishers, and add a field named TitlesCount that ' holds the number of titles by each publisher. rs.Open "SHAPE {SELECT * FROM Titles} AS Titles " _ & "COMPUTE Titles, COUNT(Titles.Title) AS TitlesCount BY PubID"
101
rs.Open " SHAPE {SELECT * FROM Titles} AS Titles2 " _ & "COMPUTE Titles2, MIN(Titles2.[Year Published]) AS YearMin, " _ & "MAX(Titles2.[Year Published]) AS YearMax, " _ & "CALC(YearMax - YearMin) AS YearDiff BY PubID"
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset Dim rsTitles As ADODB.Recordset cn.Open "Provider=MSDataShape.1;Data Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=" & DBPATH Set rs.ActiveConnection = cn rs.Open "SHAPE {SELECT * FROM Titles} AS Titles " _ & "COMPUTE Titles, COUNT(Titles.Title) AS TitlesCount BY PubID" ' Have the rsTitles variable always point to the child Recordset. ' (The StayInSync property's default value is True.) Set rsTitles = rs("Titles").Value ' Browse the parent Recordset. Do Until rs.EOF ' Show information in summary fields. Debug.Print "PubID=" & rs("PubID") Debug.Print "TitlesCount=" & rs("TitlesCount") ' For each row in the parent, browse the child recordset. Do Until rsTitles.EOF Debug.Print " " & rsTitles("Title") rsTitles.MoveNext Loop rs.MoveNext Loop
102
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset, Dim cmd As New ADODB.Command, source As String cn.Open "Provider=MSDataShape.1;Data Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\Microsoft Visual Studio\Vb98\biblio.mdb" source = "SHAPE {SELECT * FROM Titles WHERE [Year Published] = 1990} " _ & "AS Titles COMPUTE Titles BY PubID" Set cmd.ActiveConnection = cn cmd.CommandText = source Set rs = cmd.Execute()
source = "SHAPE {SELECT * FROM Titles WHERE [Year Published] = @1} " _ & "AS Titles COMPUTE Titles BY PubID" cmd.CommandText = ReplaceParams(source, "1990") Set rs = cmd.Execute()
103
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset cn.Open "Provider=MSDataShape.1;Data Provider=sqloledb.1;" _ & "Data Source=p2;user id=sa;initial catalog=pubs" Set rs.ActiveConnection = cn rs.Open "SHAPE {SELECT * FROM Publishers} " _ & "APPEND ({SELECT * FROM Titles WHERE pub_id = ?} " _ & "RELATE pub_id TO PARAMETER 0) AS Titles"
' Continuing the previous code example... ' Print the number of titles for US publishers. (This is just an example: ' in a real program you should add a WHERE clause to the Open method.) Dim rs2 As ADODB.Recordset Set rs2 = rs("titles").Value ' Make the assignment just once. Do Until rs.EOF If rs("country") = "USA" Then ' The next statement actually retrieves the records from Titles. Print rs("pub_name"), rs2.RecordCount End If rs.MoveNext Loop
104
105