DataAdapter.Fill 给出错误 "Could not find server 'System' in sys.servers."

DataAdapter.Fill gives error "Could not find server 'System' in sys.servers."

我正在尝试从我的 SQL 服务器数据库中获取一些值,我可以通过以下方式连接到它:

SqlConnection conx = new SqlConnection();
SqlConnection conx4 = new SqlConnection("Data Source=.\Sistema_Deci;Initial Catalog=sistema_decisiones_financieras;Persist Security Info=True;User id=sa;Password=somepassword;timeout=120;");
conx = conx4;

conx.Open();
conx.Close();

到目前为止一切顺利,但是当我尝试从中获取值时出错,代码如下:

try
{
    SqlCommand cmd2 = new SqlCommand("SELECT * FROM Ordenes_Servicios", conx);
    SqlDataReader reader1;
    DataTable dtordenes = new DataTable();

    conx.Open();

    SqlDataAdapter sqlDA = new SqlDataAdapter(cmd2.ToString(), conx.ConnectionString);
    sqlDA.Fill(dtordenes);  // <--- at this point the error occurs

    conx.Close();
}
catch(Exception ex)
{}
            

例外情况是:

System.Data.SqlClient.SqlException (0x80131904): Could not find server 'System' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.

到目前为止,我已经在 SQL 服务器上尝试查看服务器的名称,显然结果中没有任何“系统”服务器,但我不明白为什么会这样尝试连接到 'System' 而不是 'Sistema_Deci'

select name from sys.servers

哦,我的 Visual Studio 是 2017(与 2019 相同的问题)和 运行 SQL Server 2019 Express,因为我无法安装我一直在使用的 2014到目前为止(我知道为什么,但它在安装 2014 时开始抛出错误)。

我找到了一种可行的方法,但这不是我尝试编程的方式,因为将所有内容映射出来需要大量额外工作

SqlCommand cmd2 = new SqlCommand("SELECT * FROM Ordenes_Servicios", conx);

SqlDataReader reader1;
DataTable dtordenes = new DataTable();

dtordenes.Columns.Add("ID");
dtordenes.Columns.Add("Cliente");

conx.Open();

reader1 = cmd2.ExecuteReader();

while (reader1.Read())
{
    string temp = reader1["ID_Reporte"].ToString();
    string temp2 = reader1["Cliente"].ToString();
    dtordenes.Rows.Add(temp, temp2);
}

这是错误的:

SqlDataAdapter sqlDA = new SqlDataAdapter(cmd2.ToString(), conx.ConnectionString);

cmd2 是一个 SqlConnection,它没有自己的 ToString,因此它使用默认的对象类型,它只是对象的类型。这意味着数据适配器看到的“SQL”最终变成了 "System.Data.SqlClient.SqlConnection" 并且您的 sqlserver 认为您正在调用另一台名为“System”的服务器上的存储过程(在名为 Data 的数据库中,在名为 SqlClient 的模式中,用于名为 SqlConnection 的过程)

只需这样做:

var dt = new DataTable();
using var da = new SqlDataAdapter("SELECT * FROM Ordenes_Servicios", conx);
da.Fill(dt);

扔掉所有其他代码;这都是无关紧要的。你只需要这 3 行。数据适配器自己知道如何打开连接

由于以下代码,您收到错误消息:

SqlDataAdapter sqlDA = new SqlDataAdapter(cmd2.ToString(), conx.ConnectionString); //SqlDataAdapter(String, String)

如果你打算使用这个重载,你可以简单地使用这样的东西:

SqlDataAdapter sqlDA = new SqlDataAdapter("SELECT * FROM Ordenes_Servicios", "Data Source=.\Sistema_Deci;Initial Catalog=sistema_decisiones_financieras;Persist Security Info=True;User id=sa;Password=somepassword;timeout=120;"); //SqlDataAdapter(String, String)

SqlDataAdapter sqlDA = new SqlDataAdapter(cmd2); //SqlDataAdapter(SqlCommand) 

SqlDataAdapter sqlDA = new SqlDataAdapter("SELECT * FROM Ordenes_Servicios", conx); //SqlDataAdapter(String, SqlConnection) 

也只保留一个连接作为conx并使用它:

SqlConnection conx = new SqlConnection("Data Source=.\Sistema_Deci;Initial Catalog=sistema_decisiones_financieras;Persist Security Info=True;User id=sa;Password=somepassword;timeout=120;");

Docs 上阅读有关 SqlDataAdapter 的更多信息。