为什么函数会产生不必要的价值

时间:2010-11-26 13:09:56

标签: c#

我有一个这样的函数用于绑定ComboBox中所选数据库的主键:

//An instance of the connection string is created to manage the contents of the connection string.

var sqlConnection = new SqlConnectionStringBuilder();
sqlConnection.DataSource = "192.168.10.3";
sqlConnection.UserID = "gp";
sqlConnection.Password = "gp";
sqlConnection.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue);
string connectionString = sqlConnection.ConnectionString;

SqlConnection sConnection = new SqlConnection(connectionString);

//To Open the connection.
sConnection.Open();

//Query to select the table_names that have PRIMARY_KEYS.
string selectPrimaryKeys = @"SELECT TABLE_NAME 
                             FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                             WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
                             ORDER BY TABLE_NAME";

//Create the command object
SqlCommand sCommand = new SqlCommand(selectPrimaryKeys, sConnection);

try
{
    //Create the dataset
    DataSet dsListOfPrimaryKeys = new DataSet("INFORMATION_SCHEMA.TABLE_CONSTRAINTS");

    //Create the dataadapter object
    SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectPrimaryKeys, sConnection);

    //Provides the master mapping between the sourcr table and system.data.datatable
    sDataAdapter.TableMappings.Add("Table", "INFORMATION_SCHEMA.TABLE_CONSTRAINTS");

    //Fill the dataset
    sDataAdapter.Fill(dsListOfPrimaryKeys);

    //Bind the result combobox with primary key tables
    DataViewManager dvmListOfPrimaryKeys = dsListOfPrimaryKeys.DefaultViewManager;
    cmbResults.DataSource = dsListOfPrimaryKeys.Tables["INFORMATION_SCHEMA.TABLE_CONSTRAINTS"];
    cmbResults.DisplayMember = "TABLE_NAME";
    cmbResults.ValueMember = "TABLE_NAME";
}
catch(Exception ex)
{
    //All the exceptions are handled and written in the EventLog.
    EventLog log = new EventLog("Application");
    log.Source = "MFDBAnalyser";
    log.WriteEntry(ex.Message);
}
finally
{
    //If connection is not closed then close the connection
    if(sConnection.State != ConnectionState.Closed)
    {
        sConnection.Close();
}

但是它给出了像dtproperties这样不需要的结果。查询有什么问题。

2 个答案:

答案 0 :(得分:1)

dtproperties是SQL Server用于存储图表信息的表。在某些版本的SQL Server中,它被标记为用户表(而不是系统表),因此将由查找用户表的查询返回。

也许只是用这样的东西过滤掉它:

string selectPrimaryKeys = @"SELECT 
                                       TABLE_NAME 
                                   FROM
                                       INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                                  WHERE 
                                       CONSTRAINT_TYPE = 'PRIMARY KEY'
                                       AND TABLE_NAME <> 'dtproperties'
                               ORDER BY 
                                       TABLE_NAME";

答案 1 :(得分:0)

虽然主键技术上是表的一部分而不是数据库,但假设您的查询正确,请尝试使用C#代码。它有一些内存和性能改进,并且它也会捕获连接异常。

public void GetPrimaryKeyTable() {
    //An instance of the connection string is created to manage the contents of the connection string.

    var sqlConnection = new SqlConnectionStringBuilder();
    sqlConnection.DataSource = "192.168.10.3";
    sqlConnection.UserID = "gp";
    sqlConnection.Password = "gp";
    sqlConnection.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue);

    // Automatically close the connection
    using(SqlConnection sConnection = new SqlConnection(sqlConnection.ConnectionString)) {
        try {
            sConnection.Open();

            //Query to select the table_names that have PRIMARY_KEYS.
            string selectPrimaryKeys = @"SELECT TABLE_NAME 
                                        FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                                        WHERE   CONSTRAINT_TYPE = 'PRIMARY KEY'
                                        ORDER   BY TABLE_NAME";

            //Create the command object
            using(SqlCommand sCommand = new SqlCommand(selectPrimaryKeys, sConnection)) {
                // Bind the combobox without destroying the data reader object after binding (no using statement)
                cmbResults.DisplayMember = "TABLE_NAME";
                cmbResults.ValueMember = "TABLE_NAME";  
                cmbResults.DataSource sReader = sCommand.ExecuteReader();
                cmbResults.DataBind();
            }
        }
        catch(Exception ex) {
            // All the exceptions are handled and written in the EventLog.
            EventLog log = new EventLog("Application");
            log.Source = "MFDBAnalyser";
            log.WriteEntry(ex.Message);
        }
        finally {
            // Read somewhere that the using statement takes care of this for you
            // but just in case
            if(sConnection.State != ConnectionState.Closed) {
                sConnection.Close();
            }
        }
    }
}

对于您的查询,在SQL Server 2008 R2中,它返回一个包含主键的表列表(列表中的每个表都是一个包含主键的表)。您使用的是哪个版本的SQL Server?

编辑:如果您希望查询仅返回USER表并过滤掉系统表之类的内容,请尝试以下查询:

SELECT  tc.TABLE_NAME 
FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
INNER   JOIN sysobjects so
        ON tc.TABLE_NAME = so.name
WHERE   tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
        AND so.xtype = 'U'
ORDER   BY TABLE_NAME;