Определение наличия БД по имени в C#
От: Аноним  
Дата: 25.02.09 10:43
Оценка:
SqlConnection testConnection = new SqlConnection(ConnectionString);
где ConnectionString — строка с параметрами, имя узла сервера БД , далее сама БД и пользователь.
Есть ли способ определить заранее существует ли БД с заданным именем на сервере?
Если можно код на C#
Re: Определение наличия БД по имени в C#
От: divergo  
Дата: 25.02.09 10:58
Оценка:
using System;

using System.Runtime.InteropServices;

using System.Text;



namespace DataUtility

{

    /// <summary>

    /// Summary description for SQLInfoEnumerator.

    /// This class Enumerates a network for SQL Server instances and returns a list.

    /// For a given SQL Server instance a list of all available databases is returned

    /// For more information see

    /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqlbrowseconnect.asp

    /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp09192002.asp

    /// 

    /// </summary>

    public class SQLInfoEnumerator

    {

        #region ODBC32 external function definitions

        [DllImport("odbc32.dll")]private static extern short SQLAllocHandle( short handleType, IntPtr inputHandle, out IntPtr outputHandlePtr );

        [DllImport("odbc32.dll")]private static extern short SQLSetEnvAttr( IntPtr environmentHandle, int attribute, IntPtr valuePtr, int stringLength );

        [DllImport("odbc32.dll")]private static extern short SQLFreeHandle( short hType, IntPtr Handle );

        [DllImport("odbc32.dll",CharSet=CharSet.Ansi)]private static extern short SQLBrowseConnect( IntPtr handleConnection, StringBuilder inConnection, short stringLength, StringBuilder outConnection, short bufferLength, out short stringLength2Ptr );

        #endregion

        #region Constants

        private const string SQL_DRIVER_STR = "DRIVER=SQL SERVER";

        private const short SQL_SUCCESS = 0;

        private const short SQL_HANDLE_ENV = 1;

        private const short SQL_HANDLE_DBC = 2;

        private const int SQL_ATTR_ODBC_VERSION = 200;

        private const int SQL_OV_ODBC3 = 3;

        private const short SQL_NEED_DATA = 99;

        private const short DEFAULT_RESULT_SIZE = 1024;

        private const string START_STR ="{";

        private const string END_STR ="}";

        #endregion

        

        /// <summary>

        /// A string to hold the selected SQL Server

        /// </summary>

        string m_SQLServer;

        /// <summary>

        /// A string to hold the username

        /// </summary>

        string m_Username;

        /// <summary>

        /// A string to hold the password

        /// </summary>

        string m_Password;

        /// <summary>

        /// Property to set the SQL Server instance

        /// </summary>

        public string SQLServer

        {

            set{m_SQLServer=value;}

        }

        /// <summary>

        /// Property to set the Username

        /// </summary>

        public string Username

        {

            set{m_Username=value;}

        }

        /// <summary>

        /// Property to set the Password

        /// </summary>

        public string Password

        {

            set{m_Password=value;}

        }

        

        /// <summary>

        /// Enumerate the SQL Servers returning a list (if any exist)

        /// </summary>

        /// <returns></returns>

        public string[] EnumerateSQLServers()

        {

            return RetrieveInformation(SQL_DRIVER_STR);

        }

        /// <summary>

        /// Enumerate the specified SQL server returning a list of databases (if any exist)

        /// </summary>

        /// <returns></returns>

        public string[] EnumerateSQLServersDatabases()

        {

            return RetrieveInformation(SQL_DRIVER_STR+";SERVER="+ m_SQLServer+";UID=" + m_Username +";PWD=" +m_Password);

        }



        /// <summary>

        /// Enumerate for SQLServer/Databases based on the passed information it the string

        /// The more information provided to SQLBrowseConnect the more granular it gets so

        /// if only DRIVER=SQL SERVER passed then a list of all SQL Servers is returned

        /// If DRIVER=SQL SERVER;Server=ServerName is passed then a list of all Databases on the

        /// servers is returned etc

        /// </summary>

        /// <param name="InputParam">A valid string to query for</param>

        /// <returns></returns>

        private string[] RetrieveInformation(string InputParam)

        {

            IntPtr m_environmentHandle=IntPtr.Zero;

            IntPtr m_connectionHandle = IntPtr.Zero;

            StringBuilder inConnection = new StringBuilder(InputParam);

            short stringLength= (short)inConnection.Length;

            StringBuilder outConnection = new StringBuilder(DEFAULT_RESULT_SIZE);

            short stringLength2Ptr= 0;

                

            try

            {    

                if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_ENV, m_environmentHandle, out m_environmentHandle))

                {

                    if (SQL_SUCCESS == SQLSetEnvAttr(m_environmentHandle,SQL_ATTR_ODBC_VERSION,(IntPtr)SQL_OV_ODBC3,0))

                    {

                        if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_DBC, m_environmentHandle, out m_connectionHandle))

                        {

                            if (SQL_NEED_DATA == SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, outConnection, DEFAULT_RESULT_SIZE, out stringLength2Ptr))

                            {

                                if (SQL_NEED_DATA != SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, outConnection, DEFAULT_RESULT_SIZE, out stringLength2Ptr))

                                {

                                    throw new ApplicationException("No Data Returned.");

                                }

                            }

                        }    

                    }

                }

            }

                        

            catch (Exception ex)

            {            

                throw new ApplicationException("Cannot Locate SQL Server.");

            }

            finally

            {

                FreeConnection(m_connectionHandle);

                FreeConnection(m_environmentHandle);

            }

            if (outConnection.ToString()!="")

            {return ParseSQLOutConnection(outConnection.ToString());}

            else{return null;}

            

            

        }

        /// <summary>

        /// Parse an outConnection string returned from SQLBrowseConnect

        /// </summary>

        /// <param name="outConnection">string to parse</param>

        /// <returns></returns>

        private string[] ParseSQLOutConnection(string outConnection)

        {

            int m_Start = outConnection.IndexOf(START_STR) + 1;

            int m_lenString = outConnection.IndexOf(END_STR) - m_Start;

            if((m_Start>0) &&(m_lenString>0))

            {outConnection = outConnection.Substring(m_Start,m_lenString);}

            else

            { outConnection = string.Empty;}

            return outConnection.Split(",".ToCharArray());

        }

        private void FreeConnection(IntPtr handleToFree)

        {

                if(handleToFree!= IntPtr.Zero)

                        SQLFreeHandle(SQL_HANDLE_DBC,handleToFree);

        }

        

    }

}
Re: Определение наличия БД по имени в C#
От: samius Япония http://sams-tricks.blogspot.com
Дата: 25.02.09 11:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>SqlConnection testConnection = new SqlConnection(ConnectionString);

А>где ConnectionString — строка с параметрами, имя узла сервера БД , далее сама БД и пользователь.
А>Есть ли способ определить заранее существует ли БД с заданным именем на сервере?
Есть
А>Если можно код на C#
с кодом сложно, т.к. он размазан по разным хелперам, но основная идея проста:
Требуется выполнить запрос типа
SELECT COUNT(name) FROM msdb.sys.databases WHERE name = @DatabaseName

через SqlConnection, созданный с master connectionString, который получить можно следующим образом:
IDbConnection CreateMasterConnection(string connectionString)
{
    var builder = new SqlConnectionStringBuilder
    {
         ConnectionString = connectionString,
         InitialCatalog = "master"
    };

    return new SqlConnection(builder.ConnectionString);
}

Параметр @DatabaseName выкусывается из ConnectionString так:

string GetDatabaseName(string connectionString)
{
     var builder = new SqlConnectionStringBuilder
     {
        сonnectionString = connectionString
     };
     return builder.InitialCatalog;
}
Re: Определение наличия БД по имени в C#
От: DNNX Беларусь http://d2nx.ru
Дата: 25.02.09 11:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>SqlConnection testConnection = new SqlConnection(ConnectionString);

А>где ConnectionString — строка с параметрами, имя узла сервера БД , далее сама БД и пользователь.
А>Есть ли способ определить заранее существует ли БД с заданным именем на сервере?
А>Если можно код на C#

Быстрый грязнохак:

SELECT DB_ID('ALL_YOUR_BASE')


Возвращает NULL если БД с именем ALL_YOUR_BASE на сервере не существует. C# кода не напишу, соре. Забыл его уже.
И, да — запрос валиден только в MS SQL Server'е.
<a href="http://d2nx.ru">Унылый бложе</a>
db_id
Re: Определение наличия БД по имени в C#
От: Аноним  
Дата: 25.02.09 11:54
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>SqlConnection testConnection = new SqlConnection(ConnectionString);

А>где ConnectionString — строка с параметрами, имя узла сервера БД , далее сама БД и пользователь.
А>Есть ли способ определить заранее существует ли БД с заданным именем на сервере?
А>Если можно код на C#

Запрос к мастер-таблицам может не прокатить, если доступа у пользователя, от которого идет запрос, к этиим таблицам нет. Можно либо сделать хранимку SP_TEST и дергать ее. Либо сделать SELECT 0 к интересующей БД и анализировать код ошибки.
Re[2]: Определение наличия БД по имени в C#
От: Аноним  
Дата: 25.02.09 16:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>SqlConnection testConnection = new SqlConnection(ConnectionString);

А>>где ConnectionString — строка с параметрами, имя узла сервера БД , далее сама БД и пользователь.
А>>Есть ли способ определить заранее существует ли БД с заданным именем на сервере?
А>>Если можно код на C#

А>Запрос к мастер-таблицам может не прокатить, если доступа у пользователя, от которого идет запрос, к этиим таблицам нет. Можно либо сделать хранимку SP_TEST и дергать ее. Либо сделать SELECT 0 к интересующей БД и анализировать код ошибки.


Можно воспользоваться мелкомягкими библиотеками

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using MSU = Microsoft.SqlServer.Management;
using System.Xml;
using System.IO;
using System.Data.Sql;
using System.Data;

///
/// . . . . . . .
///

String connServer = "...";
String connDB = "...";
String coonUser = "...";
String connPwd = "...";
String connString = "User ID=" + coonUser + "; pwd=" + connPwd + "; Database=" + connDB + "; Data Source=" + connServer;

MSU.Common.ServerConnection sc = new MSU.Common.ServerConnection(new System.Data.SqlClient.SqlConnection(connString));
MSU.Smo.Server srv = new MSU.Smo.Server(sc);
MSU.Smo.Database db = srv.Databases[connDB];// srv.Databases — коллекция баз на сервере connServer
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.