我在使用此任务之前已经来到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();
}
干杯, 凯。
答案 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的一面,您可以使用给定的字体,大小和尺寸来测量显示给定文本所需的空间字体特征。
马克