【问题标题】:How to get server name (only without SQL Server instance) from connection string如何从连接字符串中获取服务器名称(仅没有 SQL Server 实例)
【发布时间】:2016-01-15 19:40:40
【问题描述】:

我想测试是否存在带有 tcp 套接字的 SQL Server(如果服务器不存在则更快)。

如果连接字符串是这样的:

name="DefaultConnection" 
connectionString="Data Source=COMPUTERNAME\SQLSERVERNAME;Initial Catalog=TestDb;Integrated Security=False;User ID=sa;Password=1234;MultipleActiveResultSets=True"/>

我想用这个方法:

public bool CheckServerAvailablity(string sServerAddressOrName)
{
        try
        {
             string connectString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectString);
            // Retrieve the DataSource property.    
            string sServerAddressOrName = builder.DataSource;
            int port = 1433;
            IPHostEntry ipHostEntry = Dns.GetHostEntry(sServerAddressOrName);
            IPAddress ipAddress = ipHostEntry.AddressList[0];

            TcpClient TcpClient = new TcpClient();
            TcpClient.Connect(ipAddress, port);
            TcpClient.Close();

            return true;
        }
        catch
        {
            return false;
        }
    } 

问题是:sServerAddressOrName = COMPUTERNAME\SQLSERVERNAME,但我只需要COMPUTERNAME

那么,问题是如何只获得COMPUTERNAME

提前致谢!

【问题讨论】:

  • 您假设 SQL Server 正在侦听 1433 端口。但是 1433 是默认实例的默认端口。命名实例默认使用动态端口。此外,可以将默认实例配置为侦听另一个端口。因此,即使对于默认实例,CheckServerAvailablity 也不起作用。从连接字符串中获取计算机名称是一个小问题,您可以使用 String.Split() 来解决它。但是获取 SQL Server 监听的端口不是,您需要与 SQL Server Browser 服务通信
  • 感谢您的评论。你说的很对,但是这个问题所属的环境,只能使用 TCP/IP 连接。

标签: c# sql-server connection-string


【解决方案1】:

你可以使用 Split() 函数来做类似的事情

string sServerAddressOrName = builder.DataSource.Split('\\')[0];

【讨论】:

  • 看到您的答案快速从/ 变为` \\ ` 到` \\ `。我知道你最终会到达那里。 ;) 编辑:哈,现在在我的评论中发生在我身上!
  • 是的,没有识别出确切的字符,但这不是重点。整个想法是使用Split() 函数。
  • 谢谢,但是如果实例名称是这样的:\\COMPUTERNAME\\SQLSERVER?
  • @Rahul,您的回答解决了获取计算机名称的问题,但并没有解决检查服务器可用性的问题。默认情况下,命名 SQL Server 实例不侦听 1433 端口
  • @NotanywhoNotanywho,在这种情况下,您将不得不更改您的 Split() 方法以在 1 处获取元素。
【解决方案2】:

SqlConnectionStringBuilderDataSource 属性获取要连接的 SQL Server 实例的名称/网络地址。

在您的情况下,它是机器的主机名和 SQL Server 实例名称,以 \ 分隔。

如果您只需要在这种特定情况下工作的东西,您可以访问 DataSource 并在 \ 字符上拆分字符串,如下所示:

String myConnectionString = "Data Source=COMPUTERNAME\\SQLSERVERNAME;Initial Catalog=TestDb;Integrated Security=False;User ID=sa;Password=1234;MultipleActiveResultSets=True";
var builder = new SqlConnectionStringBuilder(myConnectionString);
String hostname = builder.DataSource.Split(new Char[] { '\\' })[0]);

也就是说,上述方法并不完全通用,并且不适用于更复杂的 DataSource 值。

Since you can't use \ in a SQL Server instance name,我们可以利用这些信息来产生一个稍微更好的解决方案:

var builder = new SqlConnectionStringBuilder(connectionString);
Int32 length = builder.DataSource.LastIndexOf('\\');
Int32 start = builder.DataSource.LastIndexOf('\\', length - 1) + 1;
if (start == length) { start = 0; } else { length -= start; }
var hostname = builder.DataSource.Substring(start, length);

但是,我应该补充一点,如果使用命名管道 (\\COMPUTERNAME\pipe\pipeName)、端口号 (COMPUTERNAME:1433) 或强制 TCP 指定数据源,即使 解决方案也将不起作用参数(即tcp:COMPUTERNAME)。

【讨论】:

  • OP已经使用了SqlConnectionStringBuilder,为什么还要链接呢?
  • @cFrozenDeath 我想我忽略了它。无论如何,我会留下它,因为它不会影响答案的其余部分。
  • 谢谢,但这个答案只能在这种特殊情况下使用。如果实例名称更复杂,则不会起作用。
  • @Joshua,谢谢!我也是这样做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多