从SqlDataReader获取列宽度

时间:2009-03-09 20:36:35

标签: width sqldatareader

我在使用此任务之前已经来到StackOverflow: MS SQL2005 Query/Stored Proc Results To Text using SqlCommand or any other method

我被告知自己构建字符串,以便从SQL Managment Studio的结果文本(Cntrl + T)获得相同的结果

我现在遇到了一个问题,如何动态确定列的宽度?那些VARCHAR(MAX)的列呢?我完全不知道SqlDataReader会在什么时候进入。

这是我到目前为止的代码,我基本上需要消除PADDING_LENGTH并动态替换它的值。

我从网上的某个地方拿了基本代码。 (谁先写了,谢谢你)

StringBuilder sb = new StringBuilder(); 
 private void GenerateResultsText(SqlDataReader reader)
    {
        const int PADDING_LENGTH = 40;

        do
        {
            // Create new data table
            DataTable schemaTable = reader.GetSchemaTable();

            if (schemaTable != null)
            {
                // A query returning records was executed
                for (int i = 0; i < schemaTable.Rows.Count; i++)
                {
                    DataRow dataRow = schemaTable.Rows[i];
                    // Create a column name that is unique in the data table
                    string columnName = (string)dataRow["ColumnName"];
                    //Add to Results String.
                    sb.Append(String.Format("{0, " + -1 * PADDING_LENGTH + "}", columnName));
                }
                sb.Append(Environment.NewLine);

                //Add markers to seperate Row entries from Column names. 
                const string columnRowSeperator = "-----"; //Keep it to a multiple of 5.
                for (int i = 0; i < schemaTable.Rows.Count; i++)
                {
                    for (int j = 0; j < PADDING_LENGTH / columnRowSeperator.Length; j++)
                        sb.Append(columnRowSeperator);
                }
                sb.Append(Environment.NewLine);

                // Fill the data table we just created
                while (reader.Read())
                {
                    Object temp;

                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        temp = reader.GetValue(i);
                        sb.Append(String.Format("{0, " + -1 * PADDING_LENGTH + "}", temp.ToString()));
                    }
                    sb.Append(Environment.NewLine);
                }

                //Add newlines to seperate tables.
                sb.Append(Environment.NewLine + Environment.NewLine);
            }
        }
        while (reader.NextResult());

        reader.Close();
        reader.Dispose();
    }

干杯, 凯。

2 个答案:

答案 0 :(得分:4)

修改

以下是使用DataReader的示例。您可以更具体地查看NumericPrecision列,例如在架构表中,但我认为这将帮助您入门。

using (SqlConnection conn = new SqlConnection("Data Source=server;Initial Catalog=db;User Id=user;Password=pass;"))
{
    using (SqlCommand cmd = new SqlCommand("select * from table", conn))
    {
        conn.Open();
        StreamWriter sw = new StreamWriter(File.Open("test.txt", FileMode.Append));        
        DataTable schema = null;

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            schema = rdr.GetSchemaTable();


            for (int i = 0; i < rdr.FieldCount; i++)
            {
                string name = schema.Rows[i]["ColumnName"].ToString();
                sw.Write(name.PadRight(name.Length + Convert.ToInt32(schema.Rows[i]["ColumnSize"])) + " ");
            }

            sw.WriteLine();

            for (int i = 0; i < rdr.FieldCount; i++)
            {
                string name = schema.Rows[i]["ColumnName"].ToString();
                sw.Write(new string('-', name.Length + Convert.ToInt32(schema.Rows[i]["ColumnSize"])) + " ");
            }

            rdr.Close();//can't have two open datareaders on the same connection
            rdr.Dispose();

            sw.WriteLine();

            while (dataReader.Read())
            {
                for (int i = 0; i < dataReader.FieldCount; i++)
                {
                    string name = schema.Rows[i]["ColumnName"].ToString();
                    sw.Write(dataReader[i].ToString().PadRight(name.Length + Convert.ToInt32(schema.Rows[i]["ColumnSize"])) + " ");
                }
                sw.WriteLine();
            }

        }

        sw.Close();
        sw.Dispose();
    }
}

我没有足够的时间来了解如何使用DataReader执行此操作,但如果您使用DataAdapter,则可以执行此操作:

    using (SqlConnection conn = new SqlConnection("Data Source=someserver;Initial Catalog=somedb;User Id=user;Password=password;"))
    {
        using (SqlCommand cmd = new SqlCommand("select * from sometable", conn))
        {
            conn.Open();
            using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
            {
                DataSet set = new DataSet();
                set.Tables.Add("Schema");
                set.Tables.Add("Data");

                adapter.Fill(set, "Data");
                adapter.FillSchema(set, SchemaType.Source, "Schema");

                StreamWriter sw = new StreamWriter(File.Open("test.txt", FileMode.Append));        

                for(int i = 0; i < set.Tables["Schema"].Columns.Count; i++)
                {

                    sw.Write(set.Tables["Schema"].Columns[i].ColumnName.PadRight(set.Tables["Schema"].Columns[i].MaxLength + set.Tables["Schema"].Columns[i].ColumnName.Length, ' ') + " ");
                }
                sw.WriteLine();

                for(int i = 0; i < set.Tables["Schema"].Columns.Count; i++)
                {
                    sw.Write(new string('-', set.Tables["Schema"].Columns[i].MaxLength + set.Tables["Schema"].Columns[i].ColumnName.Length) + " ");
                }
                sw.WriteLine();

                foreach(DataRow row in set.Tables["Data"].Rows)
                {
                    foreach(DataColumn col in set.Tables["Data"].Columns)
                    {
                        sw.Write(row[col].ToString().PadRight(set.Tables["Schema"].Columns[col.ColumnName].MaxLength + col.ColumnName.Length) + " ");
                    }
                    sw.WriteLine();
                }

                sw.Close();
                sw.Dispose();






            }
        }
    }

答案 1 :(得分:0)

您无法仅通过Sql Data Reader确定要在屏幕上显示的列的宽度 - 毕竟,列的宽度在很大程度上取决于您使用的屏幕字体,大小,粗体与否以及等等。

您需要做的是将文本渲染到您想要显示它的UI中 - 在UI的一面,您可以使用给定的字体,大小和尺寸来测量显示给定文本所需的空间字体特征。

马克