Category Archives: Software development

How to Create SQL Azure Database Users With Microsoft Access VBA

Why do we need a SQL Azure Database User Account? An Access Database cannot access SQL Azure Objects such as Tables, Views, or Stored Procedures without one. That is, unless you use your SQL Azure Administrator account which would be living very dangerously if you were distributing your database to others. So before your database can do anything with SQL Azure, a Database User Account must be created that it can use. Also permissions must be granted to use the necessary SQL Azure Tables, Views, and Stored Procedures. We are going to show you how you can use a pass-through query in Access to create SQL Azure Database Users using Access VBA.

Database users must be created in the database in which they will exist because the “USE” statement can only work for the current database in SQL Azure. So to create a Database User we must use a query that runs in the Database in which we want to create the User. And since it would be confusing, to me at least, to log in using “JoeDeveloper” and work as Database User “SamCodeSlinger” my normal practice is to create a Database User with the same name as a Login Name.

If we were using SQL Server Management Studio (SSMS) or the Windows Azure Management Portal we could create a Database User as shown with the following Transact-SQL (T-SQL):

CREATE USER MyLoginName FOR LOGIN MyLoginName

Or:

CREATE USER MyLoginName FROM LOGIN MyLoginName

But you can easily create Database Users with Microsoft Access using the following two procedures, passing the Login Name to the CreateSQLAzureDBUser Function:

 

'Example usage: Call CreateSQLAzureDBUser("MyLoginName")
Public Function CreateSQLAzureDBUser(strLoginName As String) As Boolean
On Error GoTo ErrHandle

    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim strSQL As String

    CreateSQLAzureDBUser = False 'Default Value

    strSQL = "CREATE USER " & strLoginName & " FOR LOGIN " & strLoginName

    'Create the Database User
    Set db = CurrentDb
    Set qdf = db.CreateQueryDef("")
    'Change obfuscatedFunctionName to the name of a Function
    'that Returns your SQL Azure Database Connection String
    qdf.Connect = obfuscatedFunctionName 
    qdf.SQL = strSQL
    qdf.ReturnsRecords = False
    qdf.Execute dbFailOnError

    'If no errors the Database User was Created
    CreateSQLAzureDBUser = True

ExitHere:
    'Cleanup for security and to release memory
    On Error Resume Next
    Set qdf = Nothing
    Set db = Nothing
    Exit Function

ErrHandle:
    MsgBox "Error " & Err.Number & vbCrLf & Err.Description _
    & vbCrLf & "In procedure CreateSQLAzureDBUser"
    Resume ExitHere

End Function

 

The Database User must be created in the Database in which it is to be used and not in the master Database. You can do this by changing MySQLAzureDatabaseName in the obfuscatedFunctionName Function to the name of the database in which you want to create the users.

 

'It is best to change the name of this procedure for better security for your use. 
'The strIn Argument value, "Wb_gR%/PD\-k&yZq~j>l", is used like a Password to keep 
'unauthorized users from getting your Connection String. You should also change it 
'to suit you before you use it in a distributed application.
Public Function obfuscatedFunctionName(strIn As String) As String

    If strIn = "Wb_gR%/PD\-k&yZq~j>l" Then
        obfuscatedFunctionName = "ODBC;" _
            & "DRIVER={SQL Server Native Client 10.0};" _
            & "SERVER=tcp:MyServerName.database.windows.net,1433;" _
            & "UID=MyUserName@MyServerName;" _
            & "PWD=MyPassword;" _
            & "DATABASE=MySQLAzureDatabaseName;" _
            & "Encrypt=Yes"
    Else
        obfuscatedFunctionName = vbNullString
    End If

End Function

 

For better security you can keep the Login Name, Password, and User Name hidden in the code without exposing it to the Access user.

We now have the ability to create Database Users but we still need to Grant Permissions before our Access Database can use this User Account to access any data in SQL Azure. We plan to show how you can do that in the articles to come.

You can download the code used in this article from our Free Code Samples page.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples

Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.

Happy computing,
Patrick (Pat) Wood
Gaining Access
http://gainingaccess.net

How to Plug Microsoft Access accde and mde Security Leaks

I was shocked. I had heard that Constants and Variables could be seen by opening an accde or mde file with a hex editor but when I opened my file I was stunned to see so much of my data, objects, and code in plain text. I am not an Access Security expert, but I decided to take on the challenge of this security issue and when I was through I was very pleased with the results. In this article we will examine the security risks of accde and mde files and present some ways you can greatly improve the security of your files.

The Bad News About accde and mde File Security

You don’t have to be an Access expert to break the security of an Access Database. Anyone can do it with a free hex editor easily downloaded from the internet. The hex editor revealed the data in every local table in my accde database and worse.

1) A Simple Hex Editor Reveals Much Information

Here is a partial list of what I was able to read with a free hex editor:

  • Names of all Tables both Local and Linked
  • All Field Names in Local Tables
  • All Values in Tables Except for Hyperlinks
  • All Query Names and Query SQL
  • All Global Constants
  • All Module Names
  • All Procedure Names
  • Most Procedure Arguments
  • Some Code in Procedures
  • Usually Two or More Variable Names in Each Procedure
  • All Form RecordSource Queries and SQL
  • All Control Names and Property Values
  • All List Box and Combo Box RowSource Queries and SQL Statements
  • All References with File Names and Full Paths

I found the code of a couple of procedures virtually intact. As we shall see, this revealed data can lead to even further exploitation.

2) Your Forms and Controls are Vulnerable

If you have controls on a form that hold sensitive data such as confidential Customer information a user can very easily get that data if they can open the database. A control with the name txtSQLServerConnection may give someone access to the company database. Who knew we were so vulnerable?

3) Those Who Know How Can Read Your Constants and Run Your Procedures

For those who know how, it is very easy to read your Constants and run your Subs and Functions. I will not reveal how it is done here, but for experienced developers it is a piece of cake.

I know of no way of safeguarding your Constants short of encrypting your database and that option is not always available. So I think it best not to use Constants for any sensitive data like Connection Strings or Passwords.

Most procedures can easily be run by those who know how. This can reveal a lot of sensitive data and if you use queries in code your database is especially vulnerable. Your data may easily be read, altered, or deleted. That is depressing enough without going further, so I will share some good news.

The Good News About accde and mde File Security

1) Encrypting Your File May Provide Greater Security

Encrypting your database with a password may provide better protection in keeping unauthorized users from getting information from your database. I wrote “may provide” because there are some cases where this does not help. Unfortunately it can’t keep the authorized users from giving their password to others or taping it on a note on their monitor or trying to hack the database themselves. The security of your database is only as strong as your weakest user. In addition, encrypting a database is not always an option for distributed applications, especially when users have different versions of Access because they can only be opened using the version of Access by which they were encrypted.

2) Obfuscate the Names of Procedures, Arguments, and Variables

Variables strA, strB, etc. are a lot better at concealing important information than strAccountNumber and strPassword. Fortunately your comments all get removed when the accde or mde file is created. So if you don’t want to purchase software to obfuscate your code for you, you can do it yourself and use comments in your original accdb or mdb file to document your code so you can always know what your code is doing.

3) Use a Procedure Argument As a “Password”

It is so very easy to run the procedures in an accde or mde file once you know how. Give me your unencrypted accde or mde file and I can be running procedures in it in less than 5 minutes without any preparation in advance. So I am not going to share that secret here. But I will share how you can easily foil this type of attack.

If we can use Passwords to open files then we can use them to protect our code from hackers who would run our procedures. When I write an important procedure I add an additional Argument that is used like a Password. When the Procedure runs it checks for that Argument and if it is not correct then the Procedure does nothing. The following example shows how this works.

'The PartColorNotes Procedure is named to mislead hackers.
'In this case it returns the SQL Azure Database Connection String
Public Function PartColorNotes(strIn As String) As String

    If strIn = "Wb_gR%/PD\-k&yZq~j>l" Then
        PartColorNotes = "ODBC;" _
            & "DRIVER={SQL Server Native Client 10.0};" _
            & "SERVER=tcp:MyServerName.database.windows.net,1433;" _
            & "UID=MyUserName@MyServerName;" _
            & "PWD=MyPassword;" _
            & "DATABASE=MySQLAzureDatabaseName;" _
            & "Encrypt=Yes"
    Else
        PartColorNotes = vbNullString
    End If

End Function

First, if I was a hacker I could not care less about the PartColorNotes. And I would definitely give up trying to run this procedure long before I discovered the “Password” and that is the point. We cannot keep the bad guys totally out of our database but we can make it so difficult to get our information it is not worth the effort. Some good news about this method is that after using my other security measures I did not see any string values in my accde and mdb files so this security measure should be very effective.

Below is a procedure that can produce the “Passwords” for your Procedure Arguments and which you can also use to create SQL Azure and SQL Server Passwords.

'---------------------------------------------------------------------------------------
' Procedure : GetPWDCharacters
' Author    : Patrick Wood  http://gainingaccess.net
' Date      : 8/10/2011
' Purpose   : Get Random Characters (These are also safe to use for ODBC Passwords)
' Arguments : lngCount is the number of characters you want returned
' Example   : strPassword = GetPWDCharacters(15) - Returns a string of 15 characters
'---------------------------------------------------------------------------------------
Function GetPWDCharacters(lngCount As Long) As String

    Dim i As Long
    Dim j As Long
    Dim arrCharacters As Variant
    Dim strCharacters As String

    'Build an array of Characters including all letters, numbers, and safe special characters
    arrCharacters = Array( _
         "o", "S", "v", "2", "y", "Z", "I", "%", "t", "x", "6", "W", "q", "_", "j", "u", _
         "8", "k", "L", ">", "m", "C", "R", "/", "P", "9", "d", "h", "^", "w", "B", "f", _
         "+", "Q", "i", "E", "&", "a", "X", "U", "=", "g", "b", "F", "$", "O", "Y", "J", _
         "3", "0", "K", "p", "~", "s", "M", "4", "H", "l", "#", "D", "G", "N", "\", "V", _
         "c", "z", "1", "5", "T", "e", "7", "n", "<", "A", "r")

    'Loop the number of times entered
    For i = 1 To lngCount
        'Get a random number to use with the array
        j = Int((UBound(arrCharacters) - LBound(arrCharacters) + 1) * Rnd + 0)

        'Get a Random character and add it to the string
        strCharacters = strCharacters & arrCharacters(j)
    Next i

    GetPWDCharacters = strCharacters

End Function

4) Use SQL Server Or SQL Azure As a Back End

The only way to secure the data in your tables is to place your tables in a secure back end database such as SQL Azure or the Free Express version of Microsoft SQL Server. SQL Server Express has excellent security features that even meets HIPA security requirements. SQL Server’s fine grained security features also enable you to Grant and Deny Permissions to SQL Server objects or individual users to Database Roles. And SQL Server Express is free for you to download and distribute.

There is no foolproof way to keep data stored in Access tables secure. Nothing I did could keep the table values from being read as plain text in a hex editor. Even if you did go through the trouble of encrypting your data before storing it in your tables, it is still too easy for someone to delete or change your data. That is why it is so great to have the free Express versions of SQL Server available to us.

If you are using SQL Azure or SQL Server linked tables in Access you can write a function that returns the Connection String such as the PartColorNotes Function above. This enables you to safely use code to access your tables. To avoid the security risks involved with using ODBC linked tables see my article entitled Building Safer SQL Azure Cloud Applications with Microsoft Access.

5) Decompile Your Database Immediately Before Creating Your accde or mde File

This is a very crucial step. This did more to keep my sensitive information from being read with a hex editor than anything else I tried, with the exception of encrypting the database with a Password. This is most effective if you use linked tables for important information which prevents a hex editor from reading the table values.

Databases need to be Decompiled because Compacting and Repairing does not remove all the old code you no longer use. It leaves behind a large amount of sensitive information that can be exploited. I found that Decompiling my database and then immediately creating an accde or mde file removed a huge amount of text, code, and other sensitive information from my file. This was so effective it restored my faith in using accde and mde databases.

Decompiling your database should be the last step you take before creating the accde or mde file. FMS provides an article with instructions that shows you how to decompile your database as well as create a shortcut that makes decompiling much easier. After decompiling your database it will usually be much smaller and less likely to have unexplained errors.

Decompiling is however an undocumented and unsupported feature so to be safe you should never decompile without making a backup copy first. It is best to keep your original file in a safe place and decompile the copy of the database.

Summary

We have looked at some of the serious security issues with accde and mde files and have presented a number of steps to greatly improve the security of your databases. You should now be able to distribute your accde and mde files with greater confidence in their security.

You can download the code used in this article from our Free Code Samples page.

Get the free Demonstration Application that shows how effectively Microsoft Access can use SQL Azure as a back end.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples

Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.

Happy computing,
Patrick (Pat) Wood
Gaining Access
http://gainingaccess.net

Return to Top

 

How to Use Microsoft Access to Create Logins in a SQL Azure Database

In this article we will demonstrate how you can use a Pass-through query in Access with VBA code to create SQL Azure Logins. Microsoft Access can then use the Login and Password to gain access to SQL Azure Tables, Views, and Stored Procedures. We will create a Login using SQL in Access similar to the following Transact-SQL (T-SQL):

CREATE LOGIN MyLoginName WITH password = ‘zX/w3-q7jU’

Thankfully, a user would never have to memorize that password! Because this Login and password would only be used by my Access application the user never sees it and does not even know it exists.

There are several steps involved in creating a Login and Password for SQL Azure. And although most T-SQL that is used in SQL Azure is exactly the same as that used with SQL Server there are some critical differences which we will address in the following steps.

 

1) Create a Strong Password that Meets the Requirements of the Password Policy.

It is very important to use Strong Passwords because the extra security is needed since we cannot use Windows Authentication with SQL Azure. Passwords must be at least 8 characters long and contain at least one number or special character such as -/~^&.

 

2) Use Characters That Do Not Conflict With ODBC Connection Strings.

To avoid errors we should not use these ODBC connection string characters []{}(),;?*!@ in our Login Name and Password.

 

3) Build a Transact-SQL Statement Which Will Create the Login.

We will use the T-SQL CREATE LOGIN statement in a Pass-through query to create the Login. Since Pass-through queries “pass” the SQL unaltered to SQL Azure most of the time the SQL is just like what we would in SQL Server Management Studio (SSMS) and as seen here:

CREATE LOGIN MyLoginName WITH password = ‘zX/w3-q7jU’

Another requirement of the CREATE LOGIN statement is that it must be the only statement in a SQL batch. So we are only going to create one Login at a time.

 

4) Ensure the Login and Password Are Created In the master Database.

This is required because “USE master” does not work in SQL Azure as it does with SQL Server because the USE statement is not supported in SQL Azure. But with Access we can create the Login in the master database by specifying the master database in our Connection String: “DATABASE=master;”. We use a Function like the one below to get the Connection String with an obfuscated name to keep it more secure.

Public Function obfuscatedFunctionName() As String
    obfuscatedFunctionName = "ODBC;" _
	    & "DRIVER={SQL Server Native Client 10.0};" _
	    & "SERVER=tcp:MyServerName.database.windows.net,1433;" _
	    & "UID=MyUserName@MyServerName;" _
	    & "PWD=MyPassword;" _
	    & "DATABASE=master;" _
	    & "Encrypt=Yes"
End Function

See my article Building Safer SQL Azure Cloud Applications with Microsoft Access for more information about securing your Access application.

 

5) Create a Function to Execute the SQL and Create the Login.

Place the ExecuteMasterDBSQL Function below in a Standard Module. This Function executes our CREATE LOGIN statement. It can be used any time you want to execute a T-SQL statement in the SQL Azure master database that does not return records. The Function returns True if the SQL was executed successfully or False if the SQL fails to be executed.

'This procedure executes Action Query SQL in the SQL Azure master database.	
'Example usage: Call ExecuteMasterDBSQL(strSQL) or If ExecuteMasterDBSQL(strSQL) = False Then
'
Function ExecuteMasterDBSQL(strSQL As String) As Boolean
On Error GoTo ErrHandle

    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef

    ExecuteMasterDBSQL = False 'Default Value

    Set db = CurrentDb

    'Create a temporary unnamed Pass-through QueryDef. This is a
    'practice recommended in the Microsoft Developer Reference.
    'The order of each line of code must not be changed or the code will fail.
    Set qdf = db.CreateQueryDef("")
    'Use a function to get the SQL Azure Connection string to the master database
    qdf.Connect = obfuscatedFunctionName
    'Set the QueryDef's SQL as the strSQL passed in to the procedure
    qdf.SQL = strSQL
    'ReturnsRecords must be set to False if the SQL does not return records
    qdf.ReturnsRecords = False
    'Execute the Pass-through query
    qdf.Execute dbFailOnError

    'If no errors were raised the query was successfully executed
    ExecuteMasterDBSQL = True

ExitHere:
    'Cleanup for security and to release memory
    On Error Resume Next
    Set qdf = Nothing
    Set db = Nothing
    Exit Function

ErrHandle:
    MsgBox "Error " & Err.Number & vbCrLf & Err.Description _
    & vbCrLf & "In procedure ExecuteMasterDBSQL"
    Resume ExitHere

End Function

 

6) Use a Form to Enter the Login Name and Password

We can make it easy for users to create a Login by using a form. To do this we need to add two text boxes and a command button to the form. Both text boxes need to be unbound. Name the text box for the Login Name txtLoginName. Name the text box for the Password txtPassword. Name the command button cmdCreateLogin. The form should look something like this, but without the extra touches for appearance sake.

Create Logins Form

Add the code below to the command button’s Click event. After the code verifies that a Login Name and Password has been entered, it calls the ExecuteMasterDBSQL Function to create the Login in our SQL Azure master database.

Private Sub cmdCreateLogin_Click()

    'Prepare a Variable to hold the SQL statement
    Dim strSQL As String

    'Build the SQL statement
    strSQL = "CREATE LOGIN " & Me.txtLoginName & " WITH password = '" & Me.txtPassword & "'"

    'Verify both a Login Name and a Password has been entered.
    If Len(Me.txtLoginName & vbNullString) = 0 Then
        'A Login Name has not been entered.
        MsgBox "Please enter a value in the Login Name text box.", vbCritical
    Else
        'We have a Login Name, verify a Password has been entered.
        If Len(Me.txtPassword & vbNullString) = 0 Then
        	'A Password has not been entered.
        	MsgBox "Please enter a value in the Password text box.", vbCritical
        Else
        	'We have a Login Name and a Password.
        	'Create the Login by calling the ExecuteMasterDBSQL Function.
	        If ExecuteMasterDBSQL(strSQL) = False Then
	    	    MsgBox "The Login failed to be created.", vbCritical
	        Else
	    	    MsgBox "The Login was successfully created.", vbInformation
	        End If
        End If
    End If
End Sub

The code in the Form checks the return value of the ExecuteMasterDBSQL Function and informs us whether or not the Login was successfully created. Once we have created a Login we can create a Database User for the Login and grant the User access to the data in the SQL Azure Database. Creating a Database User for the Login appears to be a good subject for another article.

Get the free Demonstration Application that shows how effectively Microsoft Access can use SQL Azure as a back end.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples

Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.

Happy computing,
Patrick (Pat) Wood
Gaining Access
http://gainingaccess.net

Microsoft Access DSN-Less Linked Tables: TableDef.Append or TableDef.RefreshLink?

When it came to creating DSN-Less Linked Tables I had always used a procedure that deleted the TableDef and appended a new one until a problem occurred. The code I was using to save Linked Tables as DSN-Less Tables was not working with some of the Views in SQL Azure. This was a serious problem because the application I was developing would be distributed to clients who would then distribute it to their clients. We did not want to use a DSN file. But now the code that normally worked without a hitch was failing.

Because I was developing for SQL Azure, I had to use SQL Azure Security which includes the Username and Password in the Connection string. Even though I explicitly set the dbAttachSavePWD (Enum Value: 131072) when I appended the new TableDefs the Connection Property of my views still did not include my Username and Password. So I quickly wrote some code to loop through the TableDef properties to see if I could discover the problem.

Sub ListODBCTableProps()

    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Dim prp As DAO.Property
    
    Set db = CurrentDb
    
    For Each tdf In db.TableDefs
        If Left$(tdf.Connect, 5) = "ODBC;" Then
            Debug.Print "----------------------------------------"
            For Each prp In tdf.Properties
                'Skip NameMap (dbLongBinary) and GUID (dbBinary) Properties here
                If prp.Name <> "NameMap" And prp.Name <> "GUID" Then
                     Debug.Print prp.Name & ": " & prp.Value
                End If
            Next prp
        End If
    Next tdf
    
    Set tdf = Nothing
    Set db = Nothing
    
End Sub

I discovered that the TableDef Attributes of the Views for which my code was not working was 536870912 but for the Tables and Views that were working it was 537001984. After checking the TableDefAttributeEnum Enumeration values I was puzzled. The Attributes value for the Views which were not working was 537001984 which is the value for dbAttachedODBC (Linked ODBC database table). And the value of the Attribute for the Tables and Views that were working was 536870912 which is not in the list. After a few moments I figured it out. I saw that if you add the dbAttachedODBC value of 536870912 to the dbAttachSavePWD value of 131072 it equals the 537001984 Attributes value of the DSN-Less Tables and Views that were set properly. This made sense since the documentation Description for dbAttachSavePWD is “Saves user ID and password for linked remote table”. Apparently the Views needed both Attributes. But how could I set it?

Even though my code explicitly set the Attributes value to dbAttachSavePWD when creating the new TableDefs it was not working. Eventually I found some code that used the TableDef.RefreshLink Method, added the TableDefs Attributes dbAttachSavePWD (131072) value, and tested it. This solution worked. Below is the code I used.

Function SetDSNLessTablesNViews() As Boolean

     Dim db As DAO.Database
     Dim tdf As DAO.TableDef
     Dim strConnection As String

     SetDSNLessTablesNViews = False 'Default Value

     Set db = CurrentDb

     'Use a Function to get the Connection string
     'Note: In actual use I never use "Connection" in my Variables or Procedure names.
     'I disguise them to make it hard for a hacker to use code to get my Connection string
     strConnection = GetCnnString()

     'Loop through the TableDefs Collection
     For Each tdf In db.TableDefs
         'Verify the table is an ODBC linked table
         If Left$(tdf.Connect, 5) = "ODBC;" Then
             'Skip System tables
             If Left$(tdf.Name, 1) <> "~" Then
                 Set tdf = db.TableDefs(tdf.Name)
                 tdf.Connect = strConnection
                 If tdf.Attributes < 537001984 Then
                     tdf.Attributes = dbAttachSavePWD 'dbAttachSavePWD = 131072
                 End If
                 tdf.RefreshLink
             End If
         End If
     Next tdf

     SetDSNLessTablesNViews = True

     Set tdf = Nothing
     Set db = Nothing

End Function

I felt better about using the tdf.RefreshLink Method rather than deleting the TableDefs and appending them again. I read that you could delete your TableDefs and not be able to append a new one if there is an error in the Connection string at this page on Doug Steele’s website at the bottom of the page.

I found an interesting discussion about whether to delete and then append a new TableDef or use the RefreshLink Method on Access Monster. However the latest Developer’s Reference documentation settles the matter for me when it states the TableDef.RefreshLink Method “Updates the connection information for a linked table (Microsoft Access workspaces only).”

You may also want to see the sample code from The Access Web by Dev Ashish using the RefreshLink Method.

Below is an example of the code used to get the Connection string. As I stated in the procedure notes I never use “Connection” in Constants, Variables, or Procedure names. Nor do I use cnn, con, cnnString, etc. Instead I disguise the name of my Procedure to make it hard for a hacker to use to get my Connection string. Constants and Procedure names, along with some variables, are easily seen by opening up even an accde or mde file with a free Hex editor unless you have encrypted the database file. If I can see the name of your Constant I can very easily get its value.

'Don't forget to change the name of this procedure
Function GetCnnString() As String

     GetCnnString = "ODBC;" _
         & "DRIVER={SQL Server Native Client 10.0};" _
         & "SERVER=MyServerName;" _
         & "UID=MyUserName;" _
         & "PWD=MyPassW0rd;" _
         & "DATABASE=MySQLDatabaseName;" _
         & "Encrypt=Yes"

End Function

You can see or download the code used in this article from our Free Code Samples page.

Get the free Demonstration Application that shows how effectively Microsoft Access can use SQL Azure as a back end.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples

Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.

Happy computing,
Patrick (Pat) Wood
Gaining Access
http://gainingaccess.net

How To’s for Microsoft Access and SQL Azure with Code

Here are some How To’s to help get you started with SQL Azure. Some of them can also help with SQL Server.

How to Create Logins in SQL Azure

Create Logins Using SQL Server Management Studio (SSMS):

Logins must be created in the master database. To create a Login in SSMS I normally right click on the server and select “New Query” which opens a blank query in the master database. It must be run from the master database because you cannot use “USE master” with SQL Azure.

T-SQL:

CREATE LOGIN MyLoginName WITH password = 'zX/w3-q7jU'
GO

To be secure Passwords must follow the required Password Policy. It is best to use Strong Passwords. They must be at least 8 characters long and contain at least one number or special character such as -/~^&. Since ODBC connection strings utilize the characters []{}(),;?*!@ they should not be used in Passwords.

Create Logins Using Microsoft Access:

You can create Logins with Microsoft Access with VBA using an unnamed temporary Pass-through QueryDef, which is a technique recommended in the Microsoft Access Developer References. You can use the following sample code, passing the Login Name and the Password to the Function:

'Example usage: Call CreateLogin("MyLoginName", "zX/w3-q7jU")

Function CreateLogin(strLoginName As String, strPW As String) As Boolean
On Error GoTo ErrHandle

    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim strSQL As String

    strSQL = "CREATE LOGIN " & strLoginName & " WITH password = '" & strPW & "'"

    Set db = CurrentDb

    'Create the Logins
    Set qdf = db.CreateQueryDef("")
    qdf.Connect = GetConnMaster 'Function to get Connection string to master database in SQL Azure
    qdf.SQL = strSQL
    qdf.ReturnsRecords = False

    qdf.Execute dbFailOnError

    'If no errors the Login was Created
    CreateLogin = True

ExitHere:
    'Cleanup for security and to release memory
    On Error Resume Next
    Set qdf = Nothing
    Set db = Nothing
    Exit Function

ErrHandle:
    CreateLogin = False
    MsgBox "Error " & Err.Number & vbCrLf & Err.Description _
    & vbCrLf & "In procedure CreateLogin"
    Resume ExitHere

End Function

Return to Top

How to Create Database Users in SQL Azure

Create Database Users With SQL Server Management Studio (SSMS):

Database users must be created in the database in which they will exist and usually the Login Name is used as the Database User Name.

T-SQL:

CREATE USER MyLoginName FOR LOGIN MyLoginName
GO

Or:

CREATE USER MyLoginName FROM LOGIN MyLoginName
GO

 

Create Database Users With Microsoft Access:

You can create Database Users with Microsoft Access using the following sample code, passing the Login Name to the Function:

'Example usage: Call CreateDBUser("MyLoginName")

Function CreateDBUser(strLoginName As String) As Boolean
On Error GoTo ErrHandle

    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim strSQL As String

    strSQL = "CREATE USER " & strLoginName & " FOR LOGIN " & strLoginName

    'Create the Database&nbspUser
    Set db = CurrentDb

    Set qdf = db.CreateQueryDef("")
    qdf.Connect = GetConnDB 'Function GetConnDB gets Connection string to the database
    qdf.SQL = strSQL
    qdf.ReturnsRecords = False

    qdf.Execute dbFailOnError

    'If no errors the Database User was Created
    CreateDBUser = True

ExitHere:
    'Cleanup for security and to release memory
    On Error Resume Next
    Set qdf = Nothing
    Set db = Nothing
    Exit Function

ErrHandle:
    CreateDBUser = False
    MsgBox "Error " & Err.Number & vbCrLf & Err.Description _
    & vbCrLf & "In procedure CreateDBUser"
    Resume ExitHere

End Function

Return to Top

How to Build an ODBC Connection String in Access

For instructions and examples on how to build and use an ODBC Connection string in VBA see my article Building Safer SQL Azure Cloud Applications with Microsoft Access

Return to Top

How to Migrate a SQL Server Database to SQL Azure by Generating Scripts

Generate a Database Script for SQL Azure from the Journey to SQL Authority with Pinal Dave blog. A very helpful article that shows how to build a SQL Azure database by generating scripts from an existing SQL Server database.

In smaller databases it may be practical to also Migrate the Data by Generating Scripts using SSMS.

How to Migrate Both Schema and Data

1) Migrate the Schema.

I recommend that you first follow the example in the article and migrate the schema first. That will give you the opportunity to make any changes that might be needed. As shown in the article you click on the “Advanced” button, followed by clicking on “Script for the database engine type”, and then selecting “SQL Azure Database”. Then click on “Types of data to script” and select “Schema only”.

2) Migrate the Data.

As before you click on the “Advanced” button and “Script for the database engine type” and then select “SQL Azure Database”. But this time select “Data only” for the “Types of data to script”. This may produce a large script depending upon the amount of data stored in the database.

Return to Top

Get the free Demonstration Application that shows how effectively Microsoft Access can use SQL Azure as a back end.

More Free Downloads:
Us or UK/AU Pop-up Calendar
Report Date Dialog Form in US or UK/AU Version.
Free Church Management Software with Contributions management.
Code Samples

Get the Access and Outlook Appointment Manager to manage all of your Outlook Calendar Appointments and Access dated information.

Happy computing,
Patrick (Pat) Wood
Gaining Access
http://gainingaccess.net

Follow

Get every new post delivered to your Inbox.