Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't immediately connect to newly-created SQL Server database

I'm creating a database using SQL Server Management Objects.

I wrote the following method to generate a database:

public static void CreateClientDatabase(string serverName, string databaseName)
{
    using (var connection = new SqlConnection(GetClientSqlConnectionString(serverName, String.Empty)))
    {
        var server = new Server(new ServerConnection(connection));
        var clientDatabase = new Database(server, databaseName);

        clientDatabase.Create();
        server.ConnectionContext.Disconnect();
    }
}

Shortly thereafter, I call another method to execute a SQL script to generate tables, etc.:

public static void CreateClientDatabaseObjects(string createDatabaseObjectsScriptPath, string serverName, string databaseName)
{
    using (var connection = new SqlConnection(GetClientSqlConnectionString(serverName, databaseName)))
    {
        string createDatabaseObjectsScript = new FileInfo(createDatabaseObjectsScriptPath).OpenText().ReadToEnd();
        var server = new Server(new ServerConnection(connection));

        server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript);
        server.ConnectionContext.Disconnect();
    }
}

The statement server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript) throws a SqlException with the message Cannot open database "The database name" requested by the login. The login failed. Login failed for user 'the user'.

If I try stepping through the statements in the debugger, this exception never happens and the script executes fine.

My only guess is that the server needs some time to initialize the database before it can be opened. Is this accurate? Is there a way to tell if a database is ready other than trying and failing to connect?

Edit: I should mention that the database is definitely being created in all cases.

Edit 2: Prior to creating the database, I call the System.Data.Entity.Database.Exists method of EntityFramework.dll to check if the database already exists. If I remove that call, everything seems to work as expected. It's almost as if that call is caching the result and messing up the subsequent connections from seeing the new database (regardless of whether or not they use Entity Framework).

Edit 3: I replaced the EntityFramework's Database.Exists method with an SMO-based approach using Server.Databases.Contains(databaseName). I get the same issue in that the database cannot be opened immediately after creating. Again, if I don't check if a database exists prior to creation I can immediately open it after creating it but I'd like to be able to check for existence prior to creation so I don't try to create an existing database.

Both the EntityFramework's Database.Exists and SMO's Server.Databases.Contains both just execute SQL that looks for the database name in master.sys.databases. I don't understand why/how this is interfering with database connections.

like image 820
GWB Avatar asked Feb 15 '12 16:02

GWB


People also ask

How do I connect to a SQL Server Server?

Servers — type the SQL Server host name and the SQL Server port in the following format. The default port number is 1433. Database — type the SQL Server database name. Click Test Connection, to validate the connection. Click Finish.

Why can't I connect to the SQL Server?

If you are using windows login, please go to SQL server configuration manager to ensure named pipes and TCP/IP is enabled. And turn off the firewall and antivirus software in the computer. Please also check the similar thread which might be helpful.

How do I create a database connection in SQL Server 2008?

In the New Relational Connection dialog box, enter the Resource Name and Description ( optional ). Click Next. In the Database Middleware Driver Selection screen, expand MS SQL Server 2008, select JDBCDrivers. Click Next. In the Authentication Mode list, select Use specified user name and password.

How do I connect to a SQL Server database using JDBC?

You can create a SQL Server database connection using a JDBC driver. After importing the TrueSight_DataMart universe as mentioned in Importing a universe that is stored in the repository, in the Repository Resources tab, click Insert Session. In the Open Session dialog box, specify the System , User Name, and Password and click OK.


2 Answers

A database that has just come online is not necessarily ready to accept connections. To identify when a database can accept connections, query the collation_name column of sys.databases or the Collation property of DATABASEPROPERTYEX. The database can accept connections when the database collation returns a non-null value.

like image 159
David Brabant Avatar answered Oct 22 '22 09:10

David Brabant


In my case it turned out that the problem is not that the newly created database is not ready. But the problem was that SqlConnection.Open() apparently used a failed cached connection, which then just returned the same error again.

When I call the static SqlConnection.ClearAllPools() method before I try to open the newly created database, it works fine!

See also this question.

like image 21
Robert Hegner Avatar answered Oct 22 '22 07:10

Robert Hegner