2012-12-28 6 views
9

używam tego kodu, aby usunąć bazę danych do C#bazie spada SQL Server za pośrednictwem C#

Int32 result = 0; 

try 
{ 
     String Connectionstring = CCMMUtility.CreateConnectionString(false, txt_DbDataSource.Text, "master", "sa", "happytimes", 1000); 

     SqlConnection con = new SqlConnection(); 
     con.ConnectionString = Connectionstring; 

     String sqlCommandText = "DROP DATABASE [" + DbName + "]"; 
     if (con.State == ConnectionState.Closed) 
     { 
      con.Open(); 
      SqlConnection.ClearPool(con); 
      con.ChangeDatabase("master"); 
      SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con); 
      sqlCommand.ExecuteNonQuery(); 
     } 
     else 
     { 
      con.ChangeDatabase("master"); 
      SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con); 
      sqlCommand.ExecuteNonQuery(); 
     } 



     con.Close(); 
     con.Dispose(); 
     result = 1; 
    } 
    catch (Exception ex) 
    { 
     result = 0; 
    } 
    return result; 

Ale pojawia się błąd

Baza aktualnie w użyciu

Czy ktoś może pomóc?

+4

http://knownexception.blogspot.com/2010/05/mssql-cannot-drop-database-because-it.html –

+0

Która linia daje wyjątek? –

+0

Możliwy duplikat http://stackoverflow.com/questions/5170429/deleting-database-from-c-sharp –

Odpowiedz

16

Spróbuj tego:

String sqlCommandText = @" 
ALTER DATABASE " + DbName + @" SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
DROP DATABASE [" + DbName + "]"; 

także upewnić że połączenie łańcuchowe domyślne cię do master bazy danych lub jakiejkolwiek innej bazy danych poza tą, którą upuszczasz!

Na marginesie, naprawdę nie potrzebujesz wszystkich tych rzeczy dookoła swoich zapytań. ConnectionState zawsze zaczyna się od Closed, więc nie musisz tego sprawdzać. Podobnie, zawijanie połączenia w bloku using eliminuje potrzebę jawnego zamykania lub likwidowania połączenia. Wszystko, co naprawdę musisz zrobić, to:

String Connectionstring = CCMMUtility.CreateConnectionString(false, txt_DbDataSource.Text, "master", "sa", "happytimes", 1000); 

using(SqlConnection con = new SqlConnection(Connectionstring)) { 
    con.Open(); 
    String sqlCommandText = @" 
     ALTER DATABASE " + DbName + @" SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
     DROP DATABASE [" + DbName + "]"; 
    SqlCommand sqlCommand = new SqlCommand(sqlCommandText, con); 
    sqlCommand.ExecuteNonQuery(); 
} 
result = 1; 
+0

Musiałem umieścić nawiasy klamrowe [] wokół 'DbName' instrukcji alter na, miałem kilka myślników w mojej nazwie DbName (GUID). Wtedy działa jak urok. –

+0

SqlCommand dziedziczy implementację IDisposable od swojej klasy nadrzędnej i powinna być chroniona w użyciu bloku. –

2

Utwórz obiekt sqlconnection dla innej bazy danych niż ta, którą chcesz usunąć.

sqlCommandText = "DROP DATABASE [DBNAME]"; 
sqlCommand = new SqlCommand(sqlCommandText , sqlconnection); 
sqlCommand.ExecuteNonQuery(); 
+1

To jest to, co wkleiłem w pytaniu. –

+1

Utwórz obiekt sqlconnection dla innej bazy danych niż ta, którą chcesz usunąć. Nie można usunąć bazy danych przy użyciu połączenia tego samego db. – sreejithsdev

+0

Zmieniłem bazę danych używając con.ChangeDatabase ("master"); –

4

Powinieneś rzucić okiem na SMO. Umożliwiają one zarządzanie wszystkimi aspektami SQL Server z kodu, w tym usuwanie baz danych.

Obiekt bazy danych ma metodę usuwania bazy danych z metody Drop.

2

W tym przypadku polecam, aby podjąć najpierw do bazy danych w trybie offline ... że zamknie wszystkie połączenia i etc ... heres artykuł o tym, jak to zrobić: http://blog.sqlauthority.com/2010/04/24/sql-server-t-sql-script-to-take-database-offline-take-database-online/

Microsoft wyraźnie stwierdza, że ​​na A database can be dropped regardless of its state: offline, read-only, suspect, and so on.this MSDN article (DROP DATABASE (Transact-SQL))

2

Połączenie puli przy zgadywaniu, użyj monitora aktywności serwera sql, aby się upewnić.

Łączenie utrzymuje połączenia z bazą danych przy życiu w buforze podręcznym, a po utworzeniu nowego, jeśli takie jest w pamięci podręcznej, przekazuje je, zamiast tworzyć nowe. Są zawieszone na domyślny czas (2 minuty, jak sądzę), jeśli nie zostaną ponownie wykorzystane w tym czasie, a następnie zostaną zabite.

Pierwszym krokiem jest połączenie się bezpośrednio do mastera, zamiast korzystania z bazy danych zmian, ponieważ podejrzewam, że zmiana bazy danych po prostu zamieni połączenia w puli.

Dodaj procedurę sprawdzania bazy danych w użyciu (użyj połączenia, aby to zrobić!). Możesz wymusić zrestartowanie bazy danych, najpierw ponownie wykonując ponownie połączenie z mastera!

Jednak wszyscy inni, którzy korzystają z bazy danych, przestaną Cię lubić ...

15

Oto jak to zrobić przy użyciu Entity Framework w wersji 6

System.Data.Entity.Database.Delete(connectionString); 
+0

Żartujesz sobie ze mnie! Nie mogłem znaleźć tego w Internecie. W szoku, że nie jest to głosowanie wyższe. – goodies4uall

+0

To najlepsza odpowiedź dla mnie! –

1

Tylko nie używać nazwy DB w ciągu połączenia.

"Data Source=.\SQLEXPRESS;Integrated Security=True;" 
Powiązane problemy