简体   繁体   English

等待创建数据库完成

[英]Wait for creation database to finish

I have a code like this: 我有这样的代码:

using (var sqlConnection = new SqlConnection(connectionString))
{
  sqlConnection.Open();
  using (var sqlCommand = new SqlCommand(scriptText, sqlConnection))
  {
    sqlCommand.ExecuteNonQuery();
  }
}

For the first time I call it to create a DB, then I form a connection string to this DB and try to do some work ( Open works fine and says the connection is actually open for this second connection). 我第一次调用它来创建一个数据库,然后我形成一个连接字符串到这个数据库,并尝试做一些工作( Open工作正常,并表示连接实际上是为第二个连接打开)。 But I get an "An existing connection was forcibly closed by the remote host" and I can see the sql logs "Could not find database ID 9. Database may not be activated yet or may be in transition". 但我得到一个“现有连接被远程主机强行关闭”,我可以看到sql日志“无法找到数据库ID 9.数据库可能尚未激活或可能正在转换”。 So, actually the ExecuteNonQuery return before the job is done. 所以,实际上ExecuteNonQuery在作业完成之前返回。 Sure, I can just spam it until a situation changes, but is there a better way to wait for DB to be ready for work? 当然,我可以直接垃圾邮件直到情况发生变化,但有没有更好的方法等待数据库准备工作?

This complete sample works for me. 这个完整的样本适合我。

It creates the database, creates a table, puts a row in the table. 它创建数据库,创建表,在表中放置一行。

Not sure what is wrong on your end. 不知道你的结果有什么问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace GranadaCoder.PlaygroundConsole.SqlStuff
{
    public class SqlPlayground
    {

        public static void EntryPointStuff()
        {
            string databaseName = "MyFirstDatabaseABC";
            string connectionString = string.Empty;
            string commandText = string.Empty;
            int returnValue = 0;
            string msg = string.Empty;

            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
            builder["Initial Catalog"] = "master";
            builder["integrated Security"] = true;
            builder["Server"] = @"MyMachine\MyInstance";
            connectionString = builder.ConnectionString;


            commandText = string.Format("IF EXISTS (Select * from sys.databases where name = N'{0}') DROP DATABASE [{0}]", databaseName);
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);

            commandText = string.Format("IF NOT EXISTS (Select * from sys.databases where name = N'{0}') CREATE DATABASE [{0}]", databaseName);
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);

            /* Change the Catalog */
            builder["Initial Catalog"] = databaseName;
            connectionString = builder.ConnectionString;


            commandText = "if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeCategory]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)    BEGIN       DROP TABLE [dbo].[CodeCategory]     END ";
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);

            commandText = "CREATE TABLE [dbo].[CodeCategory] (    CodeCategoryKey           [smallint] not null     , CodeCategoryName      varchar(64) not null  ) ";
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);


            commandText = "INSERT INTO [dbo].[CodeCategory] (     CodeCategoryKey       , CodeCategoryName    ) Select 1001 , 'MyFirstCodeCategory' ";
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);

            commandText = "Select Count(*) from [dbo].[CodeCategory]";
            returnValue = RunACommand(connectionString, commandText);
            msg = string.Format("'{0}', {1}", returnValue, commandText);
            Console.WriteLine(msg);

        }




        private static int RunACommand(string connectionString, string scriptText)
        {

            int returnValue = 0;

            using (var sqlConnection = new SqlConnection(connectionString))
            {
                sqlConnection.Open();
                using (var sqlCommand = new SqlCommand(scriptText, sqlConnection))
                {
                    returnValue = sqlCommand.ExecuteNonQuery();
                }
                sqlConnection.Close();
            }

            return returnValue;
        }






    }

}

This works for me (with no exceptions): 这对我有用(没有例外):

    static void Main(string[] args)
    {

        try
        {

            SqlPlayground.EntryPointStuff();

            Console.WriteLine("Press Enter after deleting the database in SSMS manually with 'Close Existing Connections' checked.");
            Console.ReadLine();

            SqlPlayground.EntryPointStuff();


        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }


        Console.WriteLine("Pressing Enter To End");
        Console.ReadLine();

    }

In my case adding Thread.Sleep(...) helped, but the root cause was that the failed connection was cached and used by method SqlConnection.Open(). 在我的情况下添加Thread.Sleep(...)帮助,但根本原因是失败的连接被缓存并由方法SqlConnection.Open()使用。 See answer for this question for this situation. 针对这种情况,请参阅此问题的答案 Clearing the pool with SqlConnection.ClearAllPools() helps. 使用SqlConnection.ClearAllPools()清除池有帮助。

Why then waiting for some seconds helps too? 为什么等待几秒钟也有帮助呢? Seems that it was enough to clear the pool automatically by timer. 似乎通过计时器自动清除池就足够了。

You may notice this problem if you are doing someting else immediately(eg updating database schema) following the creation. 如果您在创建后立即执行其他操作(例如更新数据库架构),则可能会注意到此问题。 Waiting for a few seconds seems to solve the problem. 等待几秒似乎解决了这个问题。

//wait for database creation
Thread.Sleep(3000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM