The ADO Object Model.

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 105

1

Dim cn As New ADODB.Connection cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source=C:\Microsoft Visual Studio\Vb98\Biblio.mdb"

cn.ConnectionString = "Provider=SQLOLEDB;Server=ServerNT;" _ & "User ID=MyID;Password=MyPWD;Data Source=Pubs"

Open [ConnectionString], [UserID], [Password], [Options]

Dim cn As New ADODB.Connection cn.Open "Provider=SQLOLEDB;Data Source=MyServer;Initial Catalog=Pubs;" _ & "User ID=sa;Password=;", , , adAsyncConnect

Execute CommandText, [RecordsAffected], [Options]

Execute(CommandText, [RecordsAffected], [Options]) As Recordset

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_Disconnect(adStatus As ADODB.EventStatusEnum, _ pConnection As 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)

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)

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

Set rs.DataSource = Adodc1

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

Open [Source], [ActiveConnection], [CursorType], [LockType], [Options]

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

Dim rs2 As ADODB.Recordset Set rs2 = rs.Clone(LockType)

Resync [AffectRecords], [ResyncValues]

23

' Print employee's first and last name. Print rs.Fields("FirstName").Value, rs.Fields("LastName").Value

Print rs("FirstName"), rs("LastName")

' 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

varArray = rs.GetRows([Rows], [Start], [Fields])

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

GetString([Format], [NumRows], [ColDelimiter], [RowDelimiter], [NullExpr])

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

' Export field names.

' Export data. ' Don't add an extra

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

Move NumRecords, [Start]

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

result = CompareBookmarks(Bookmark1, Bookmark2)

Update [fields] [, values]

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

rs.AddNew rs("FirstName") = "Robert" rs("LastName") = "Doe rs("BirthDate") = #2/5/1955# rs.Update

' 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

rs.Delete rs.MoveNext If rs.EOF Then rs.MoveLast

' 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.

Find Criteria, [SkipRecords], [SearchDirection], [Start]

' 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

LIKE 'J*'" LIKE 'J__'" LIKE '*A*'" LIKE '*A'"

' Matches "Joe" and "John". ' Matches "Joe" but not "John". ' Matches "Anne", "Deborah", ' This gives an error: a bug?

UpdateBatch [AffectRecords]

CancelBatch [AffectRecords]

30

Save [FileName], [PersistFormat]

' 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

rs.Open "SELECT * FROM Employees;SELECT * FROM Customers"

Dim RecordsAffected As Long Set rs = rs.NextRecordset(RecordsAffected)

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(adBookmark) Then currBookmark = rs.Bookmark

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)

Private Sub rs_EndOfRecordset(fMoreData As Boolean, _ 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"

For i = 0 To rs.Fields.Count _ 1 lstFieldNames.AddItem rs.Fields(i).Name Next

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

Append(Name, Type, [DefinedSize], [Attrib]) As Field

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

Execute([RecordsAffected], [Parameters], [Options]) As Recordset

' 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#))

Set rs = cmd.Execute(, Array(, #1/1/1994#))

46

CreateParameter([Name], [Type], [Direction], [Size], [Value]) As Parameter

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"

Dim tbl As New ADOX.Table tbl.Name = "Customers"

' Create a table.

52

tbl.Columns.Append "CustID", adInteger tbl.Columns.Append "Name", adWVarChar, 50 cat.Tables.Append tbl

' 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

Dim cmd As ADODB.Command Set cmd = cat.Views("All Titles").Command MsgBox cmd.CommandText

' 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

If permissions If permissions If permissions If permissions If permissions Permissions"

And And And And And

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"

cn.Open "File Name=C:\Program Files\Common Files\ODBC\Data Sources\" _ & "Pubs.dsn"

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

cn.Open "Provider=Microsoft.Jet.OLEDB.3.51;" _ & "Data Source=E:\Microsoft Visual Studio\VB98\Biblio.mdb

cn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;" _ & " Data Source=MyServer;Initial Catalog=Pubs;"

cn.Open "Provider=SQLOLEDB.1;Data Source=MyServer;User ID=sa;" _ & "Password=mypwd;Initial Catalog=Pubs"

rs.Open "Authors", "Provider=SQLOLEDB.1;Data Source=MyServer;User ID=sa;" _ & "Connection Timeout=10;Initial Catalog=Pubs"

cn.ConnectionString = "Provider=MSDASQL.1;User ID=sa;" _ &"ExtendedProperties=""DRIVER= SQL Server;SERVER=ServerNT;"_ &"MODE=Read;WSID=P2;DATABASE=pubs"""

59

' You can omit the Provider argument because you're using MSDASQL. cn.ConnectionString = "DRIVER={SQL Server};SERVER= MyServer;"_&"UID=sa;DATABASE=pubs"

cn.Properties("Jet OLEDB:Database Password") = "mypwd"

' 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"

cn.Open "Provider=SQLOLEDB.1;Data Source=MyServer;User ID=sa;" _

60

& "Password=mypwd;Initial Catalog=Pubs"

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

rs2.Open "Publishers", rs.ActiveConnection

' 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

rs.MoveFirst Set DataGrid1.DataSource = rs

' 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.EditMode = adEditInProgress Then. . .

If rs.Supports(adUpdate) Then. . .

rs.Delete rs.MoveNext

71

If rs.EOF The rs.MoveLast

' 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

sql = "INSERT INTO Employees (LastName, FirstName, BirthDate) " _

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

If rs.Status And adRecModified Then. . .

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

rs.Properties("Update Criteria") = adCriteriaTimeStamp

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

cmd.ActiveConnection = "Provider=sqloledb;Data Source=p2;User Id=sa;" _ & "Initial Catalog=pubs" cmd.Execute 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.

Set rs.Source = cmd rs.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)

cmd.Parameters.Refresh (optional). cmd.Parameters(0) = "USA" cmd.Parameters(1) = "N%" Set rs = cmd.Execute()

' Create the collection

' 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

Private Sub rs_WillChangeField(ByVal cFields As Long,

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

Private Sub rs_FieldChangeComplete(& )

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

' In the WillMove event If txtCountry.Text = "" Then rs("country") = "USA"

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"

If cn.State And adStateExecuting Then. . .

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

Create Procedure PubsByCountry As

96

Select Select Select Select

pub_name pub_name pub_name pub_name

From From From From

Publishers Publishers Publishers Publishers

where where where where

country='USA' country='France' country='Germany' country='Italy'

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

SHAPE {child_command} [[AS] table_alias] COMPUTE aggregate_command_field_list [BY grp_field_list]

' 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

Dim Set Set Set

cmd As ADODB.Command, rs As ADODB.Recordset cmd = DataEnvironment1.Commands("Authors") rs = cmd.Execute MSHFlexGrid1.DataSource = rs

104

DataEnvironment1.Authors Set MSHFlexGrid1.DataSource = DataEnvironment1.rsAuthors

105

You might also like