Ошибка СОЗДАНИЯ ТАБЛИЦЫ в базе данных SQL Azure с использованием SMO - PullRequest
1 голос
/ 27 апреля 2011

Поскольку USE [dbname] не поддерживается в SQL Azure, я пытаюсь подключиться к своей базе данных SQL Azure, указав имя базы данных в строке подключения, а затем выполнив сценарий CREATE TABLE.... Однако это не удается с System.Data.SqlClient.SqlException «В базе данных« master »отказано в разрешении CREATE TABLE». Что я делаю не так, когда пытаюсь выполнить этот оператор для master?

Вот пример кода C #: string connectionString = @"Data Source=tcp:MYSERVER.database.windows.net;Initial Catalog=MYDATABASE;Integrated Security=False;User ID=USER@MYSERVER;Password=PWD;Connect Timeout=60;Encrypt=True;TrustServerCertificate=True";</p> <p>using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); ServerConnection serverConnection = new ServerConnection(connection); Server server = new Server(serverConnection); server.ConnectionContext.ExecuteNonQuery("CREATE TABLE New (NewId int)"); }

Ответы [ 3 ]

8 голосов
/ 28 апреля 2011

Оказывается, было много проблем с кодом, который у меня был.SMO все еще довольно дурацкий, когда дело доходит до SQL Azure.Итак, публикуя мои выводы на случай, если кто-то идет по той же каменистой дороге.

  1. SMO переключает базу данных по умолчанию за кулисы каждый раз, когда вы получаете объект базы данных, подобный этому:
    
    Database database = server.Databases[databaseName]
    
    Первоначальный каталог становится Masterи вы можете увидеть это в строке подключения, которая изменяется в server.ConnectionContext.ConnectionString («нормальный» SQL этого не делает).Для этого было разрешено открывать новое соединение (и закрывать старое) каждый раз, когда база данных переключается на Master, так как имя базы данных не может быть изменено после установления соединения (очевидно, только SQL Azure может это сделать).
  2. Открытие соединения, при котором инициализируются ServerConnection и Server, иногда может завершиться неудачей в связи с первой проблемой.Это может привести к неясному сообщению об ошибке, в котором будет указано, что при входе в систему произошел сбой, а также указание времени и отметки о времени обращения в службу поддержки.Ерунда.Решением этой проблемы было , а не , чтобы открыть соединение и позволить ServerConnection открыть его во время инициализации объекта Server:
  3. Наконец, Alter () не нравится SQL Azure для объекта Server.Убрал всех Алтеров.

Итак, окончательный фрагмент кода выглядит примерно так:


       string connectionString = "Server=tcp:XXXXX.database.windows.net;Database=XXXXXX;User ID=XXXXXX;Password=XXXXX;Trusted_Connection=False;Encrypt=True;trustservercertificate=true";
       SqlConnection connection = new SqlConnection(connectionString);
       // do not explicitly open connection, it will be opened when Server is initialized
       // connection.Open();

       ServerConnection serverConnection = new ServerConnection(connection);
       Server server = new Server(serverConnection);

       // after this line, the default database will be switched to Master
       Database database = server.Databases["MyDatabase"];

       // you can still use this database object and server connection to 
       // do certain things against this database, like adding database roles 
       // and users      
       DatabaseRole role = new DatabaseRole(database, "NewRole");
       role.Create();

       // if you want to execute a script against this database, you have to open 
       // another connection and re-initiliaze the server object
       server.ConnectionContext.Disconnect();

       connection = new SqlConnection(connectionString);
       serverConnection = new ServerConnection(connection);
       server = new Server(serverConnection);
       server.ConnectionContext.ExecuteNonQuery("CREATE TABLE New (NewId int)");

А вот неясное исключение для пункта № 2, если кому-то это интересно:


Microsoft.SqlServer.Management.Common.ConnectionFailureException was unhandled
  Message=Failed to connect to server .
  Source=Microsoft.SqlServer.Smo
  StackTrace:
       at Microsoft.SqlServer.Management.Smo.DatabaseCollection.get_Item(String name)
       InnerException: System.Data.SqlClient.SqlException
       Message=Login failed for user 'XXXXXXXX'.
       This session has been assigned a tracing ID of 'XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'.  Provide this tracing ID to customer support when you need assistance.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=14
       LineNumber=65536
       Number=18456
       Procedure=""
       Server=tcp:XXXXXXXX.database.windows.net
       State=1
       StackTrace:
            at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
            at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
            at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
            at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
            at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject)
            at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
            at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
            at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
            at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
            at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
            at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
            at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
            at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
            at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
            at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
            at System.Data.SqlClient.SqlConnection.Open()
            at Microsoft.SqlServer.Management.Common.ConnectionManager.InternalConnect(WindowsIdentity impersonatedIdentity)
            at Microsoft.SqlServer.Management.Common.ConnectionManager.Connect()
0 голосов
/ 28 марта 2014

И еще одна вещь, которая помогла мне - ServerConnection должен быть отключен для каждой операции.

using (var connection = new SqlConnection(parameters.ConnectionStringToMasterDatabase))
            {
                var serverConnection = new ServerConnection(connection);
                try
                {
                    var server = new Server(serverConnection);
                    // do something
                }
                finally
                {
                    serverConnection.Disconnect();
                }
            }
using (var connection = new SqlConnection(parameters.ConnectionStringToMasterDatabase))
            {
                var serverConnection = new ServerConnection(connection);
                try
                {
                    var server = new Server(serverConnection);
                    // do something else
                }
                finally
                {
                    serverConnection.Disconnect();
                }
            }
0 голосов
/ 14 ноября 2011

Просто дикое предположение, основанное на строке подключения, которая работает для меня.

Вы пытались использовать

База данных = MYDATABASE

вместо

Исходный каталог = MYDATABASE

в строке подключения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...