Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server

Programmatically Enumerating, Attaching, and Detaching SQL Server Databases

4.62/5 (12 votes)
2 Jun 2010CPOL6 min read 1  
Programmatically Enumerating, Attaching, and Detaching SQL Server Databases via SQL statements and stored procedures

هذا الموضوع متوفر أيضا باللغة العربية. 

Contents

  • Overview
  • Introduction
  • Enumerating Databases on a Server
    • INFORMATION_SCHEMA.SCHEMATA System View
    • sys.sysdatabases System Table/View
    • sys.databases System View
    • sys.sp_databases Stored Procedure
  • Attaching Databases to the Server
    • CREATE DATABASE Statement
    • sys.sp_attach_db Stored Procedure 
    • sys.sp_attach_single_file_db Stored Procedure
  • Detaching Databases from the Server
    • CREATE DATABASE Statement
    • sys.sp_detach_db Stored Procedure
  • Security Considerations

Overview

This writing is like an encyclopedia for SQL statements and stored procedures used to enumerate, attach, and detach databases on a SQL Server instance. It lists the statements and stored procedures that you can use and discusses them in simple examples.

Introduction

Today we are going to talk about how to programmatically enumerate databases on a SQL Server instance and how you can attach and detach SQL Server databases.

Enumerating Databases on a Server

You can get a list of databases on a server using one of many ways:

  • INFORMATION_SCHEMA.SCHEMATA system view (SQL Server 2000 only)
  • sys.sysdatabases system table (a view in SQL Server 2005 and higher versions)
  • sys.databases system view (SQL Server 2005 and higher versions)
  • sys.sp_databases stored procedure

INFORMATION_SCHEMA.SCHEMATA System View

If you are using SQL Server 2000, you can query the system view INFORMATION_SCHEMA.SCHEMATA to get information about current databases on the server.

The following is the table diagram for INFORMATION_SCHEMA.SCHEMATA system view:

Actually, you don't need to worry about any of the view columns, just the first column, CATALOG_NAME, that you need to worry about, is the database (i.e. catalog) name.

The following code simply prints out the databases currently found on the default SQL Server instance in the current machine:

C#
// C# Code

SqlConnection conn = new SqlConnection("Server=(local);	Data Source=;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand("", conn);
SqlDataReader rdr;

cmd.CommandText = "SELECT DISTINCT    _
	CATALOG_NAME    FROM    INFORMATION_SCHEMA.SCHEMATA";

conn.Open();

rdr = cmd.ExecuteReader();
while (rdr.Read())
{
    Console.WriteLine(rdr.GetString(0));
}

rdr.Dispose();
cmd.Dispose();
conn.Dispose();
VB.NET
' VB.NET

Dim conn As New SqlConnection("Server=(local);Data Source=;Integrated Security=SSPI")
Dim cmd As New SqlCommand("", conn)
Dim rdr As SqlDataReader

cmd.CommandText = "SELECT DISTINCT    CATALOG_NAME    FROM    INFORMATION_SCHEMA.SCHEMATA"

conn.Open()

rdr = cmd.ExecuteReader()
While (rdr.Read())
    Console.WriteLine(rdr.GetString(0))
End While

rdr.Dispose()
cmd.Dispose()
conn.Dispose() 

Again, this is for SQL Server 2000 only.

Check the MSDN documentation for INFORMATION_SCHEMA.SCHEMATA system view here.

sys.sysdatabases System Table/View

This is a system table specific to SQL Server 2000. In SQL Server 2005 it is provided for backward compatibility as a system view. Therefore, do not rely on this system view (or table) because it is expected to be removed in a future version of SQL Server.

The definition of this table/view is as follows:

Only the first column, name, is the most important to us, it contains the database name. Other columns of importance (not for the subject of this topic) are:

  • dbid: Database ID
  • sid: Security ID for the database
  • crdate: Creation date of the database
  • filename: Database filename

You can change the line that sets the command text in the previous code to this line:

C#
// C# Code

cmd.CommandText = "SELECT [name]    FROM    sys.sysdatabases";
VB.NET
' VB.NET Code

cmd.CommandText = "SELECT [name]    FROM    sys.sysdatabases" 

Again, using the sys.sysdatabases system table/view is not recommended because it would be removed in a future version of SQL Server.

Check the MSDN documentation for sys.sysdatabases system view/table here.

Check this MSDN article out: Mapping System Tables to System Views for more information about SQL Server 2000 tables mapped to SQL Server 2005 views or stored procedure.

sys.databases System View

This is the new version included in SQL Server 2005 (and higher versions) replaces the SQL Server 2000 sys.sysdatabases table.

This is a very lengthy system view, it includes tenths of columns, we are interested only in the first column, name, that contains the database name.

You can change the line that sets the command text in the first code to this line:

C#
// C# Code

cmd.CommandText = "SELECT [name]    FROM    sys. databases";
VB.NET
' VB.NET Code

cmd.CommandText = "SELECT [name]    FROM    sys. databases" 

Check the MSDN documentation for sys.sysdatabases system view/table here

sys.sp_databases Stored Procedure

This way is different from all others because it is not a system view or a system table, it is a system stored procedure.

This stored procedure accepts no parameters and returns a result set of three columns:

  • DATABASE_NAME: The name of the database
  • DATABASE_SIZE: The size of the database (in kilobytes)
  • REMARKS: Always NULL. For the Database Engine

The following code demonstrates this stored procedure:

C#
// C# Code 

cmd.CommandText = "exec sys.sp_databases";
VB.NET
' VB.NET Code

cmd.CommandText = "exec sys.sp_databases" 

Check the MSDN documentation for sys.sysdatabases system view/table here.

Attaching Databases to the Server

You can programmatically attach a database to the server in two ways:

  1. Using the CREATE DATABASE statement
  2. Using the sys.sp_attach_db system stored procedure
  3. Using the sys.sp_attach_single_file_db system stored procedure

CREATE DATABASE Statement

The CREATE DATABASE statement can be used to create databases into the server or to attach existing database files.

If you are going to attach a database, this statement should be formed as the following:

SQL
CREATE DATABASE database_name
    ON <filespec> [ ,...n ]
    FOR ATTACH [;]

The database_name is the name that you wish to give to the database. In addition, this statement takes filegroups of the database files.

Keep in mind that the database name should not exist on the server or the function would fail.

The following example shows how you can attach the database database.mdf to the server and give it the name MyDatabase:

C#
// C# Code

SqlConnection conn = new SqlConnection("Server=(local);
	Data Source=;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand("", conn);

cmd.CommandText =
    "CREATE DATABASE 'MyDatabase' ON " +
    "PRIMARY ( FILENAME =  'database.mdf' ) " +
    "FOR ATTACH";

conn.Open();

cmd.ExecuteNonQuery();

cmd.Dispose();
conn.Dispose(); 
VB.NET
' VB.NET Code

Dim conn As New SqlConnection("Server=(local);Data Source=;Integrated Security=SSPI")
Dim cmd As New SqlCommand("", conn)

cmd.CommandText = "CREATE DATABASE 'MyDatabase' ON " & _
    "PRIMARY ( FILENAME =  'database.mdf' ) " & _
    "FOR ATTACH"

conn.Open()

cmd.ExecuteNonQuery()

cmd.Dispose()
conn.Dispose() 

If no log file (.LDF) can be found, SQL Server creates one for you.

The following code attaches the same database along with its log file. Just change the third line of the previous example that sets the command text with this line:

C#
// C# Code

cmd.CommandText = "CREATE DATABASE 'MyDatabase' ON " +
        "PRIMARY ( FILENAME =  'database.mdf' ), " +
        "FILEGROUP MyDatabase_Log ( FILENAME = 'database.ldf')" +
        "FOR ATTACH"; 
VB.NET
' VB.NET Code

cmd.CommandText = "CREATE DATABASE 'MyDatabase' ON " & _
        "PRIMARY ( FILENAME =  'database.mdf' ), " & _
        "FILEGROUP MyDatabase_Log ( FILENAME = 'database.ldf')" & _
        "FOR ATTACH" 

Check the MSDN documentation for the CREATE DATABASE statement here

More about database files and filegroups can be found in the MSDN documentation here

sys.sp_attach_db Stored Procedure

Another way that allows to attach a database to the server is the sys.sp_attach_db stored procedure. The definition of this stored procedure is as follows:

SQL
sp_attach_db [ @dbname= ] 'dbname', [ @filename1= ] 'filename_n' [ ,...16 ]

This function takes the database name as the first argument. In addition, it accepts another 16 arguments (only the first is required) to represent database files. The following code attaches the same database to the server. Again, just change the third line of the previous code to the following line:

C#
// C# Code

cmd.CommandText = "exec sys.sp_attach_db    MyDatabase,    'database.mdf'"; 
VB.NET
' VB.NET Code

cmd.CommandText = "exec sys.sp_attach_db    MyDatabase,    'database.mdf'" 

Check the MSDN documentation for the sys.sp_attach_db statement here.

sys.sp_attach_single_file_db Stored Procedure

This statement is the same as sys.sp_attach_db stored procedure. However, this statement accepts only one file, the database file.

Check out the following code:

C#
// C# Code

cmd.CommandText = "exec sys.sp_attach_single_file_db    MyDatabase,    'database.mdf'"; 
VB.NET
' VB.NET Code

cmd.CommandText = "exec sys.sp_attach_single_file_db    MyDatabase,    'database.mdf'" 

Check the MSDN documentation for the sys.sp_attach_single_file_db statement here.

Detaching Databases from the Server

Unlike attaching databases, you can detach a database from a server in only two ways:

  1. DROP DATABASE statement
  2. sys.sp_detach_db system stored procedure

DROP DATABASE Statement

This statement is used to remove one or more databases from SQL Server. It has the following syntax:

SQL
DROP DATABASE database_name [ ,...n ] [;]

The following code simply executes this statement against our database MyDatabase:

C#
// C# Code

SqlConnection conn = new SqlConnection("Server=(local);	Data Source=;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand("", conn);

cmd.CommandText = "DROP DATABASE MyDatabase";

conn.Open();

cmd.ExecuteNonQuery();

cmd.Dispose();
conn.Dispose();
VB.NET
' VB.NET Code

Dim conn As New SqlConnection("Server=(local);Data Source=;Integrated Security=SSPI")
Dim cmd As New SqlCommand("", conn)

cmd.CommandText = "DROP DATABASE MyDatabase"

conn.Open()

cmd.ExecuteNonQuery()

cmd.Dispose()
conn.Dispose() 

Check the MSDN documentation for the sys.sp_attach_single_file_db statement here.

sys.sp_detach_db Stored Procedure

Huh, the last one. This stored procedure is used to detach a database from the server. It has the following syntax:

SQL
sp_detach_db [ @dbname= ] 'database_name'

It accepts a single argument, the database name. The following code removes our database, MyDatabase, from the server:

C#
// C# Code

cmd.CommandText = "sys.sp_detach_db MyDatabase"; 
VB.NET
' VB.NET Code

cmd.CommandText = "sys.sp_detach_db MyDatabase" 

Check the MSDN documentation for the sys.sp_attach_single_file_db statement here.

Security Considerations

Every statement and stored procedure we discussed in this writing requires specific permissions. Check the MSDN documentation to get more information.

Filed under: CodeProject, Data Access, SQL Server Tagged: .NET, ADO.NET, CodeProject, CSharp, SQL Server

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)