【问题标题】:Getting Column Width from SqlDataReader从 SqlDataReader 获取列宽
【发布时间】:2010-10-12 07:00:25
【问题描述】:

我曾带着这个任务来到 StackOverflow: MS SQL2005 Query/Stored Proc Results To Text using SqlCommand or any other method

我被告知要自己构建字符串,以便获得与 SQL Managment Studio 的 Results To Text (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();
    }

干杯, 凯。

【问题讨论】:

    标签: width sqldatareader


    【解决方案1】:

    您不能仅通过 Sql 数据阅读器确定要在屏幕上显示的列的宽度 - 毕竟,列的宽度在很大程度上取决于您使用的屏幕字体、大小、粗体与否以及以此类推。

    您需要做的是将文本呈现到您想要显示它的 UI 中 - 在 UI 方面,您可以测量使用给定字体、大小和显示给定文本所需的空间字体特征。

    马克

    【讨论】:

    • 我打算将此构建的字符串保存到纯文本文件中,而不是将其放在 DataGrid 或类似的东西上。我只想从 Sql Management Studio 获得与 Results to Text 相同的输出,仅此而已...... :(
    • OK - 好吧,在这种情况下,您只需要遍历所有行并获取返回的字符串的长度 - 例如通过在 SQL Server 中使用 LEN(...) 或在 C# 中使用 (value).ToString().Length()。
    【解决方案2】:

    编辑

    这是一个使用 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();
    
    
    
    
    
    
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2011-03-07
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2013-07-18
      • 2019-10-09
      • 2013-08-09
      • 1970-01-01
      • 2015-04-04
      相关资源
      最近更新 更多