How to Create a Database Snapshot and Store it in a SQLLocalDB Database

Description

Having a way to create and share data in databases is desireable in some situations. Test databases, sample databases, or databases shipped with an app can be created using database snapshots.

Discussion

Snapshots of tables and databases are created using the SQL::DatabaseSnapshot and SQL::TableSnapshot classes. Data in a snapshot can be loaded from and saved to any database that can be accessed with AlphaDAO connection strings. Data from databases can also be saved in other formats, such as XML, Excel, or JSON.

This article explains how to create a snapshot of a single table from an Access database and store it in a SQL Server LocalDB database. The LocalDB database is created as a file defined by the dbFilename variable.

Once the database has been created, a LocalDB .mdf file can be detached and shared with others. In addition to creating the LocalDB database, this article also explains how to detatch and attach LocalDB databases in Alpha Anywhere.

This article requires Alpha Anywhere build 3875 or newer.

 Loading the Table Snapshot

The first step is to create the table snapshot of the Northwind Customers table. Create and open a SQL::Connection to the Northwind Access database. If you have never worked with the Northwind Access database in Alpha Anywhere, a few extra steps are required so the database can be accessed. Follow the instructions in the "Creating AlphaDAO Connection Strings" tutorial to configure the Northwind Access database.

' Open the source database
dim cn as SQL::Connection
cn.open("::Name::Northwind_Access")
 
' Get the table info for Customers
dim ti as SQL::TableInfo
cn.getTableInfo(ti,"Customers")

' Load the table snapshot
dim ts as SQL::TableSnapshot
ts.load(cn,ti)

In the code above, three things are happening. The first is the connection to the Northwind Access database is created. Next, the table info for the Customers table is retrieved from the database. The table info is needed so the table snapshot object knows what table to load. On the last line, ts.load(cn,ti), the table snapshot is loaded using the connection string cn to load the Customers table, as defined by the table info object ti.

 Creating the LocalDB Database

Since we want to save the snapshot in a portable SQLLocalDB .mdf file, the next step in this process is to create the .mdf file. To do this, a second connection string, cn2 is needed. This connection string will be used to first create the "Northwind_Snapshot.mdf" file. In the third step, cn2 will be reused to open a connection to the Northwind_snapshot.mdf database to store the table snapshot.

' Define connection string for connecting to SQLLocalDB 2016
dim conn as c = "{A5API='SQLServer',A5DBVersion=2016,Server='(localdb)\MSSQLLocalDB',A5ANSINullPadWarn=Default,Trusted_connection=yes,A5LoginTimeout=30}"

' Open the connection
dim cn2 as SQL::Connection
cn2.open(conn)

' Create the new database
dim dbFilename as c = "C:\path\to\Northwind_Snapshot.mdf"
cn2.execute("CREATE DATABASE Northwind_Snapshot ON (name='Northwind_Snapshot', filename='" + dbFilename + "')")

' Close the connection
cn2.close()

 Saving the Table Snapshot

Now that the database has been created, the table snapshot of the Customers table can be stored in the Northwind_Snapshot database.

' Create and open a connection to the Northwind_Snapshot database
conn = "{A5API='SQLServer',A5DBVersion=2016,Server='(localdb)\MSSQLLocalDB',A5ANSINullPadWarn=Default,Trusted_connection=yes,A5LoginTimeout=30,Database='Northwind_Snapshot'}"
cn2.open(conn)

' Store the table snapshot
ts.store(cn2)

' Close all connections
cn2.close()
cn.close()

 Detaching a LocalDB Database

If you want to share the .mdf file containing the table snapshot or relocate it to another location on the file system, the LocalDB database must be detached from the SQLLocalDB instance:

' Create and open the connection
dim connStr as C = "{A5API='SQLServer',A5DBVersion=2016,Server='(localdb)\MSSQLLocalDB',A5ANSINullPadWarn=Default,Trusted_connection=yes,A5LoginTimeout=30}"
dim cn as SQL::Connection
cn.open(connStr)

' Take the database offline
cn.execute("ALTER DATABASE [Northwind_Snapshot] SET OFFLINE WITH ROLLBACK IMMEDIATE")

' Detatch the database
dim args as SQL::Arguments
args.set("dbname","Northwind_Snapshot")
cn.execute("exec sp_detach_db :dbname", args)

' Close the connection
cn.close()

Once the database is detached, it can be copied or distributed. Components that require a database to work are easier to share with a sample database. Simply zip the .mdf file with the component that uses the database to distribute them together.

 Attaching a LocalDB Database

Others who receive the LocalDB .mdf file will need to attach the database to their local instance of SQLLocalDB. This is done as follows:

' Define the absolute file path and name for the database to attach
dim mdfName as C = "C:\path\to\Northwind_Snapshot.mdf"

' Define the connection string
dim connStr as C = "{A5API='SQLServer',A5DBVersion=2016,Server='(localdb)\MSSQLLocalDB',A5ANSINullPadWarn=Default,Trusted_connection=yes,A5LoginTimeout=30}"

' Create and open the connection string
dim cn as sql::Connection
cn.open(connStr)
cn.PortableSQLEnabled = .f.

' Create the SQL statement for attaching the database
' Note: The database name must be unique
dim sql as c =<<%sql%
CREATE DATABASE Northwind_Snapshot ON
(FILENAME= '{mdfName}')
FOR ATTACH
%sql%

' Replace {mdfName} with the name of the file
sql = evaluate_string(sql)

' Attach the database
cn.execute(sql)

' Close the connection string
cn.close()

After the database has been attached, a connection string can be created to access the database. This can be done using the AlphaDAO Connection String dialog or with Xbasic, as shown below:

' Define the connection string
dim connStr as C = "{A5API='SQLServer',A5DBVersion=2016,Server='(localdb)\MSSQLLocalDB',A5ANSINullPadWarn=Default,Trusted_connection=yes,A5LoginTimeout=30,Database='Northwind_Snapshot'}"

' Save the connection string
a5_connstringoperation("cs","Northwind_Snapshot","Save","",connStr)

For more information about Database Snapshots and LocalDB, check out the links below.

See Also