[英]Can't immediately connect to newly-created SQL Server database
我正在使用SQL Server管理對象創建數據庫。
我編寫了以下方法來生成數據庫:
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();
}
}
此后不久,我調用另一種方法來執行SQL腳本來生成表格等:
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();
}
}
語句server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript)
拋出SqlException
,並顯示消息無法打開登錄請求的數據庫“數據庫名稱”。 登錄失敗。 用戶'用戶'登錄失敗。
如果我嘗試單步執行調試器中的語句,則此異常永遠不會發生,並且腳本執行正常。
我唯一的猜測是服務器需要一些時間來初始化數據庫才能打開它。 這准確嗎? 有沒有辦法告訴數據庫是否准備就緒,而不是嘗試連接失敗?
編輯:我應該提到數據庫肯定是在所有情況下創建的。
編輯2:在創建數據庫之前,我調用EntityFramework.dll的System.Data.Entity.Database.Exists方法來檢查數據庫是否已存在。 如果我刪除該調用,一切似乎都按預期工作。 這幾乎就好像該調用緩存結果並弄亂后續連接看到新數據庫(無論它們是否使用實體框架)。
編輯3:我使用Server.Databases.Contains(databaseName)
替換了EntityFramework的Database.Exists
方法和基於SMO的方法。 我得到同樣的問題,因為創建后無法立即打開數據庫。 同樣,如果我在創建之前沒有檢查數據庫是否存在,我可以在創建之后立即打開它,但我希望能夠在創建之前檢查存在,所以我不會嘗試創建現有數據庫。
EntityFramework的Database.Exists
和SMO的Server.Databases.Contains
執行在master.sys.databases中查找數據庫名稱的SQL。 我不明白為什么/如何干擾數據庫連接。
剛剛上線的數據庫不一定准備接受連接。 要確定數據庫何時可以接受連接,請查詢sys.databases的collation_name列或DATABASEPROPERTYEX的Collation屬性。 當數據庫排序規則返回非空值時,數據庫可以接受連接。
在我的情況下,事實證明問題不是新創建的數據庫沒有准備好。 但問題是SqlConnection.Open()
顯然使用了失敗的緩存連接,然后再次返回相同的錯誤。
在我嘗試打開新創建的數據庫之前調用靜態SqlConnection.ClearAllPools()
方法時,它工作正常!
另見這個問題。
這里要注意的一件事是錯誤信息是圍繞安全性的。 您是如何嘗試登錄新數據庫的(即用於新數據庫連接的連接字符串是什么類型的安全性)? 如果您使用的是SQL身份驗證,則需要發出sp_adduser以授予對數據庫的登錄訪問權限。
您必須接近數據庫創建有點不同。 下面的代碼正確處理數據庫創建。 試試吧 ;)
private void CreateDatabase(string databaseName) { Microsoft.SqlServer.Management.Smo.Server sqlServer = new Microsoft.SqlServer.Management.Smo.Server(_connection); Database createdDatabase = new Database(); createdDatabase.Name = databaseName; createdDatabase.Parent = sqlServer; createdDatabase.Create(); }
在下面的代碼中,_connection是一個
Microsoft.SqlServer.Management.Smo.ServerConnection順便提一下對象。
[編輯]修改代碼,以便不再吞下異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.