1

我之前带着这个任务来到了 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();
    }

干杯,凯。

4

2 回答 2

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();






            }
        }
    }
于 2009-03-09T21:26:55.920 回答
0

您不能仅从 Sql 数据阅读器确定要在屏幕上显示的列的宽度 - 毕竟,列的宽度在很大程度上取决于您使用的屏幕字体、大小、粗体或不加粗等等。

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

马克

于 2009-03-09T20:41:37.090 回答