The desired SQL statement is:
IF DB_ID('testdb') IS NULL CREATE DATABASE [testdb]
The T-SQL expression to build up this statement is:
N'IF DB_ID(' +
QUOTENAME(@DatabaseName, '''') +
N') IS NULL CREATE DATABASE ' +
QUOTENAME(@DatabaseName)
Notice the use of QUOTENAME
to wrap testdb
in quotes and in brackets.
QUOTENAME(@DatabaseName)
generates [testdb]
QUOTENAME(@DatabaseName, '''')
generates 'testdb'
QUOTENAME helps prevent potential SQL injection.
Always use it in dynamic SQL, even when you are 100% certain your input is sanitized; for two reasons.
- Nothing is 100% certain. There's nothing wrong with a healthy dose of suspicion, even when it concerns your own code.
- Your code makes a bad example for other (less experienced) developers.
Unfortunately, the syntax of EXECUTE
is rather limited; function calls are not allowed in the string expression.
We need a temporary variable to build up the SQL statement.
DECLARE @DatabaseName nvarchar(50) = N'testdb';
DECLARE @creator nvarchar(200) =
N'IF DB_ID(' +
QUOTENAME(@DatabaseName, '''') +
N') IS NULL CREATE DATABASE ' +
QUOTENAME(@DatabaseName)
EXECUTE (@creator)
Dynamic SQL really hurts readability; it is all too easy to make mistakes.
A good way to analyze bugs is to let the generated SQL statement be printed rather than executed.
- Temporarily replace
EXECUTE (@creator)
with PRINT @creator
- Run the SQL script in SSMS; the generated SQL statement will appear in the output pane of SSMS.
- Copy/paste the output into another query window. Now it's easy to spot the syntax errors; just look for red squiggly lines.
- Test the generated script, but fix the bugs in the generating script.
- Repeat the preceding steps until it works.
I strongly recommend to wrap the SQL script above in a stored procedure, as it allows you to properly manage the required permissions, as explained in the article
Packaging Permissions in Stored Procedures by Erland Sommarskog.
CREATE PROCEDURE CreateDatabaseIfNotExists @DatabaseName nvarchar(50) AS
DECLARE @creator nvarchar(200) =
N'IF DB_ID(' +
QUOTENAME(@DatabaseName, '''') +
N') IS NULL CREATE DATABASE ' +
QUOTENAME(@DatabaseName)
EXECUTE (@creator)
You can now call the stored procedure from C#. As there is no dynamic SQL here, you do not need to worry about escaping characters in the database name.
using (var con = new SqlConnection(YourConnectionString))
using (var cmd = new SqlCommand("CreateDatabaseIfNotExists", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@DatabaseName", SqlDbType.VarChar).Value = YourDatabaseName;
con.Open();
cmd.ExecuteNonQuery();
}