C# SQL连接字符串返回错误

3

你好,我对连接服务器/数据库这方面是新手,想知道为什么会出现错误。

我有一个FastHost服务器和一个数据库。

我只是举了一个例子IP地址,但我一直在使用控制面板上网站提供的IP地址。

private void SQLTest_Click(object sender, RoutedEventArgs e)
            {
                SqlConnection conn = new SqlConnection();
                conn.ConnectionString =
                    "Data Source = 123.456.789.012" +
                    "Initial Catalog = DiscoverThePlanet" +
                    "User ID = TestUser" +
                    "Password = Test";
                try
                {
                    conn.Open();
                    MessageBox.Show("Connection Established!");
                    conn.Close();
                }

                catch (Exception ex)
                {
                    MessageBox.Show("Can not open Connection!");
                }
            }

这将返回“无法打开连接!”的消息。

我在代码中看到以下内容:

发生了类型为'System.Data.SqlClient.SqlException'的异常,但在用户代码中没有处理。

额外信息:建立与 SQL Server 的连接时出现特定于网络或特定于实例的错误。找不到服务器或无法访问服务器。请验证实例名称是否正确,并验证是否已配置 SQL Server 以允许远程连接(提供程序:命名管道提供程序,错误:40 - 无法打开到 SQL Server 的连接)。

我知道我的服务器没问题,因为我已经在 SQL Server 管理工具上连接到它并添加了表和数据。

6个回答

7

你少了几个;

conn.ConnectionString =
                    "Data Source = 123.456.789.012" +
                    ";Initial Catalog = DiscoverThePlanet" +
                    ";User ID = TestUser" +
                    ";Password = Test";

更好的解决方案是使用 ConnectionStringBuilder

System.Data.SqlClient.SqlConnectionStringBuilder builder =
  new System.Data.SqlClient.SqlConnectionStringBuilder();
builder["Data Source"] = "123.456.789.012";
builder["Initial Catalog"] = "DiscoverThePlanet";
builder["User ID"] = "TestUser";
builder["Password"] = "Test";
Console.WriteLine(builder.ConnectionString);

或者(正如@Fischermaen所提到的那样),您可以使用属性而不是索引。这样更易读!

    builder.DataSource = "123.456.789.012";
    builder.InitialCatalog = "DiscoverThePlanet";
    builder.UserID = "TestUser";
    builder.Password = "Test";

此外,在这种情况下,您没有使用任何用户输入,但要注意手动创建连接字符串时可能会发生 连接字符串注入ConnectionStringBuilder 可以帮助您避免这些问题。
当使用动态字符串串联来基于用户输入构建连接字符串时,可能会发生连接字符串注入攻击。如果没有验证并且未转义恶意文本或字符,则攻击者可能会访问服务器上的敏感数据或其他资源。例如,攻击者可以通过提供分号并附加附加值来发起攻击。连接字符串使用“最后一个获胜”算法进行解析,并将敌对输入替换为合法值。
连接字符串生成器类旨在消除猜测工作并防止语法错误和安全漏洞。它们提供与每个数据提供程序允许的已知键/值对相对应的方法和属性。每个类维护一组固定的同义词,并且可以从同义词翻译到相应的众所周知的键名称。检查有效的键/值对,并且无效的对会抛出异常。此外,注入的值以安全方式处理。
一个最后(也是我认为最好的)的选择是将连接字符串从代码中移动到配置文件中。这样可以让您更轻松地在不同的环境中使用相同的代码。
conn.ConnectionString = ConfigurationManager.ConnectionStrings["MyConnectionString];

还有您的配置。

<connectionStrings>
    <add name="MyConnectionString" connectionString="[ConnectionString goes here]" providerName="System.Data.SqlClient" />
</connectionStrings>

太棒了,我没想到这是如此简单的事情。 - Luke Litherland
1
使用ConnectionStringBuilder是你提到的一个好点,但我更喜欢使用属性而不是索引器!比如 'builder.DataSource = "123.456.789.012"' - Fischermaen
@smoksnes:很棒,你提到了“连接字符串注入”!!! - Fischermaen
我很高兴你提到了注入问题,这些都是非常有帮助的信息,所以谢谢你! - Luke Litherland
我也喜欢使用属性的想法,所以感谢 @Fischermaen。 - Luke Litherland

2
在连接字符串代码的每个部分之后添加分号:
private void SQLTest_Click(object sender, RoutedEventArgs e)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString =
                "Data Source = 123.456.789.012;" +
                "Initial Catalog = DiscoverThePlanet;" +
                "User ID = TestUser;" +
                "Password = Test";
            try
            {
                conn.Open();
                MessageBox.Show("Connection Established!");
                conn.Close();
            }

            catch (Exception ex)
            {
                MessageBox.Show("Can not open Connection!");
            }
        }

https://www.connectionstrings.com/sql-server/应该会告诉你更多关于正确格式的信息。


2

您的连接字符串格式不正确,您忘记了一些 ;

"Data Source = 123.456.789.012;Initial Catalog = DiscoverThePlanet;User ID = TestUser;Password = Test" 

一个例子:
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;

https://www.connectionstrings.com/sql-server/


1

有些分号丢失了。尝试这个:

conn.ConnectionString =
                    "Data Source = 123.456.789.012;" +
                    "Initial Catalog = DiscoverThePlanet;" +
                    "User ID = TestUser;" +
                    "Password = Test;";

0
如果您想编写像提到的那样的 ConnectionString,请使用 StringBuilder。
每次使用 String 对象时,它都会占用内存。
StringBuilder 只会占用一次内存,因此它将为您提供更好的性能。
SqlConnection conn = new SqlConnection();
StringBuilder sb=new StringBuilder();
sb.Append("Data Source = 123.456.789.012;");
sb.Append("Initial Catalog = DiscoverThePlanet;");
sb.Append("User ID = TestUser;");
sb.Append("Password = Test;");
conn.ConnectionString =sb.ToString();
try
{
    conn.Open();
    MessageBox.Show("Connection Established!");
    conn.Close();
}

catch (Exception ex)
{
    MessageBox.Show("Can not open Connection!");
}

使用 StringBuilder 构建连接字符串对我来说就像用大锤砸坚果一样;-) 不要误会,StringBuilder 对于大量的字符串操作非常有帮助,但是对于构建连接字符串来说,它看起来有点过度设计了。 - Fischermaen
没错,如果只执行一次的话没有问题,我建议OP在将来需要连接字符串的其他地方使用String-builder。 - Sandip - Frontend Developer

0

连接字符串中缺少分号,请进行更正。

private void SQLTest_Click(object sender, RoutedEventArgs e)
        {
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString =
                "Data Source = 123.456.789.012;" +
                "Initial Catalog = DiscoverThePlanet;" +
                "User ID = TestUser;" +
                "Password = Test;";
            try
            {
                conn.Open();
                MessageBox.Show("Connection Established!");
                conn.Close();
            }

            catch (Exception ex)
            {
                MessageBox.Show("Can not open Connection!");
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接