Redgate Test Data Manager

Subsetting SQL Server worked example

This section guides you through a worked subsetting example in SQL Server. It includes steps to create a small source database and to create an empty target database from it, which is then used in the subsetting example. It provides links to further examples and to resources to understand how the subsetter works.

Contents

Preparation

Preparation of Subsetter

Please do the following before beginning the worked example

  1. Install the subsetter CLI.
  2. Verify your installation by running the following command in a terminal window:
    1. Windows cmd: subsetter.exe --version
    2. Windows PowerShell: ./subsetter --version
    3. Linux: ./subsetter --version

The subsetter should report its version number as below (example in Windows cmd).

C:\Subsetting\>Subsetter.exe --version
0.8.0.0

Preparation of Database Engine

Microsoft SQL Server comes with a command-line SQL query tool, sqlcmd. It can be found under the directory where you have installed Microsoft SQL Server, in Windows this is typically C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn. You can run sqlcmd by opening a command prompt directly in this directory, or add the directory to your PATH environment variable to enable running sqlcmd from any where on your computer.

Enter sqlcmd in a command prompt and you should see the following:

1>

Now you have entered sqlcmd and you should be able to execute SQL queries against the databases you created. To exit sqlcmd, simply type:

quit

Create a source database

Create an empty database

Create an empty database called SourceDatabase in SQL Server.

You can do this using a graphical tool like SQL Server Management Studio (SSMS).

Alternatively you can do this by executing this SQL query below, either in SSMS or in sqlcmd.

CREATE DATABASE [SourceDatabase]; 
go

Populate the database

Download the SQL script sample-sql-server-database.sql and execute it in the new database. 

Again, you can do this using SSMS, or you can execute the command below at a command prompt (NOT inside sqlcmd): 

sqlcmd -d SourceDatabase -i sample-sql-server-database.sql

This will create a sample database with four tables, containing example data. It represents a simple social media website, where users create posts and comment on posts, and users belong to organizations.

Check the database contents

Check that the tables exist and contain data. Use SSMS, or use a SQL query as below which lists all the table names:

SELECT TABLE_NAME FROM SourceDatabase.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE';
go

And a SQL query as below which to list the data in a table:

SELECT * FROM SourceDatabase.dbo.Users;
go

Create an empty target database

Run the SQL script given below. This will create a new database called TargetDatabase. It will have the same tables as the SourceDatabase, but without any data rows.

DBCC CLONEDATABASE(SourceDatabase, TargetDatabase) WITH VERIFY_CLONEDB;
go
ALTER DATABASE [TargetDatabase] SET READ_WRITE WITH ROLLBACK IMMEDIATE;
go

Verify that the target database exits with the same schema as the source database and is empty. 

Run the subsetter

The commands below run the subsetter. If the commands cannot run successfully, you may need to work through the connection strings section below to configure them to your environment.

Click on the sections below to view the example command lines:

./subsetter.exe `
--database-engine sqlserver `
--source-connection-string "server=localhost;database=SourceDatabase;trusted_connection=yes;TrustServerCertificate=yes" `
--target-connection-string "server=localhost;database=TargetDatabase;trusted_connection=yes;TrustServerCertificate=yes" `
--starting-table "[dbo].[Users]" `
--filter-clause "[OrgId] = 1"
subsetter.exe ^
--database-engine sqlserver ^
--source-connection-string "server=localhost;database=SourceDatabase;trusted_connection=yes;TrustServerCertificate=yes" ^
--target-connection-string "server=localhost;database=TargetDatabase;trusted_connection=yes;TrustServerCertificate=yes" ^
--starting-table "[dbo].[Users]" ^
--filter-clause "[OrgId] = 1"
#!/usr/bin/env bash
./subsetter \
--database-engine sqlserver \
--source-connection-string "server=localhost;database=SourceDatabase;trusted_connection=yes;TrustServerCertificate=yes" \
--target-connection-string "server=localhost;database=TargetDatabase;trusted_connection=yes;TrustServerCertificate=yes" \
--starting-table "[dbo].[Users]" \
--filter-clause "[OrgId] = 1"

Connection strings

You may need to change the connection strings to suit your environment. The connection strings identify the source and target database.

The connection strings in the example above use Windows security. An alternative is to set trusted_connection=false , and use uid=username  and pwd=userpassword to specify a username and password with SQL Server's integrated security.

We have further advice on connection strings in our troubleshooting and known limitations section. There is also a lot of information online about connection strings. Here are some tips:

  • Use server to specify the SQL Server instance containing the databases. In the example above we are using localhost to connect to an instance running on the same computer that is running the subsetter.
  • Use appropriate attributes to connect to the instance in a secure way. The example uses TrustServerCertificate to connect to a locally-hosted instance of SQL Server which uses a self-signed certificate. This may not be appropriate in your case. You may wish to ask your IT department for advice.

Output from the command

The command will produce detailed output similar to that shown below. The details may vary. Check that the last line of output says Subsetting completed.

2023-11-02 16:50:47.320 +00:00 [INFO] Subsetter has started in 'Release' mode. Log folder is C:\ProgramData\Red Gate\Logs\TDM\Subsetter.
2023-11-02 16:50:47.400 +00:00 [INFO] Validating subsetting configuration data...                                                       
2023-11-02 16:50:47.901 +00:00 [INFO] Found starting table 'dbo.Users' with 12 row(s) in 'SourceDatabase' database on 'localhost' server
2023-11-02 16:50:47.905 +00:00 [INFO] Applying filter clause '[OrgId] = 1' to starting table 'dbo.Users' produced 5 row(s).            
2023-11-02 16:50:47.908 +00:00 [INFO] Completed initial validation of subsetting configuration data in 00h 00m 00s.507ms              
2023-11-02 16:50:47.928 +00:00 [INFO] Application Insights telemetry is disabled and events will not be sent.                             
2023-11-02 16:50:47.931 +00:00 [INFO] Running SqlServer database table extraction using 'SourceDatabase' database on 'localhost' server...
2023-11-02 16:50:48.105 +00:00 [INFO] Successfully extracted 12 table(s) (with 4 relationships) from 'SourceDatabase' database on 'localhost' serv
er in 00h 00m 00s.173ms.
2023-11-02 16:50:48.108 +00:00 [INFO] Starting to build database migration model from source 'SourceDatabase' database on 'localhost' server...   
2023-11-02 16:50:48.121 +00:00 [INFO] Successfully built database migration model in 00h 00m 00s.012ms for starting tables 'dbo.Users' and clause '[
OrgId] = 1' with 4 step(s)
2023-11-02 16:50:48.124 +00:00 [INFO] Running SqlServer database table extraction using 'TargetDatabase' database on 'localhost' server...        
2023-11-02 16:50:48.334 +00:00 [INFO] Successfully extracted 5 table(s) (with 4 relationships) from 'TargetDatabase' database on 'localhost' serve
r in 00h 00m 00s.210ms.
2023-11-02 16:50:48.337 +00:00 [INFO] Validating source 'SourceDatabase' database on 'localhost' server and target 'TargetDatabase' database on 'l
ocalhost' server structure...
2023-11-02 16:50:48.361 +00:00 [INFO] Completed validation of source 'SourceDatabase' database on 'localhost' server and target 'TargetDatabase' d
atabase on 'localhost' server structure in 00h 00m 00s.023ms...
2023-11-02 16:50:48.439 +00:00 [INFO] [Pre-Cleanup] Constraints successfully disabled on target 'TargetDatabase' database on 'localhost' server. T
his is temporary and only during the duration of the subsetting operation (they will be restored at the end).
2023-11-02 16:50:48.442 +00:00 [INFO] Starting subset data creation in source 'SourceDatabase' database on 'localhost' server (via temporary table
s)...
2023-11-02 16:50:48.495 +00:00 [INFO] Successfully created 4 temporary tables to hold the subset results in source 'SourceDatabase' database on 'l
ocalhost' server in 00h 00m 00s.052ms.
2023-11-02 16:50:48.498 +00:00 [INFO] Starting subset data copy from 4 temporary tables in source 'SourceDatabase' database on 'localhost' server 
to target 'TargetDatabase' database on 'localhost' server...
2023-11-02 16:50:48.547 +00:00 [INFO]   dbo.RG3TEMP_Users    --> dbo.Users    : 5 row(s)
2023-11-02 16:50:48.566 +00:00 [INFO]   dbo.RG3TEMP_Posts    --> dbo.Posts    : 4 row(s)
2023-11-02 16:50:48.576 +00:00 [INFO]   dbo.RG3TEMP_Comments --> dbo.Comments : 2 row(s)
2023-11-02 16:50:48.581 +00:00 [INFO]   dbo.RG3TEMP_Orgs     --> dbo.Orgs     : 1 row(s)
2023-11-02 16:50:48.584 +00:00 [INFO] Subset complete. Successfully copied 4 subset tables from source 'SourceDatabase' database on 'localhost' se
rver into target 'TargetDatabase' database on 'localhost' server in 00h 00m 00s.085ms.
2023-11-02 16:50:48.594 +00:00 [INFO] [Post-Cleanup] Constraints successfully re-enabled on target 'TargetDatabase' database on 'localhost' server
.
2023-11-02 16:50:48.605 +00:00 [INFO] [Post-Cleanup] Successfully deleted 4 temporary tables on source 'SourceDatabase' database on 'localhost' se
rver as they are no longer needed.
2023-11-02 16:50:48.639 +00:00 [INFO] Subsetting completed in 00h 00m 00s.710ms.

Check the data in the target database

Check the contents of the tables in the target database. You should find that each table contains some data rows, but fewer than in the source database.

Congratulations! This shows that the subset has been created successfully.

Further examples

The documentation on configuration files explains the formats and provides worked examples of their use, that build on this worked example. 

If you want to experiment with different filter clauses, please checkout subsetting example filter clauses. You might find it helpful to apply --target-database-write-mode Overwrite so that you can reuse the target database which has now been written to.

Learning more about how the subsetter works

Now that you have carried out the worked example, you might like to understand more about how the subsetter works. Please consult the page Using the worked example to understand the subsetter. This page uses the output and the commands from the worked example to explain how the subsetter produces a referentially intact subset.


Didn't find what you were looking for?