Я написал метод, который сохраняет содержимое определенной таблицы в текстовый файл. К сожалению, имена столбцов не извлекаются. «Только» данные каждой ячейки записываются в текстовый файл.
Как мне адаптировать свой код, чтобы он также включал имена столбцов?
private void WriteSQLQueryOutputToTextFile(string DBUser, string DBUserPassword, string sqlQuery, string databaseName, string nameOfOutputFile, string nameOfRow0, string nameOfRow1, string nameOfRow2)
{
StreamWriter outputFile = new StreamWriter(dWTestResult + "\\DatabaseUpgradeCheck\\" + nameOfOutputFile);
using (SqlConnection sqlCon = new SqlConnection("Data Source = " + GetEnvironmentVariable.MachineName + "; Initial Catalog = " + databaseName + "; User ID = " + DBUser + "; Password = " + DBUserPassword + ";"))
{
SqlCommand command = new SqlCommand(sqlQuery, sqlCon);
sqlCon.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
outputFile.WriteLine(String.Format("{0}, {1}, {2}",
reader[nameOfRow0], reader[nameOfRow1], reader[nameOfRow2]));
}
}
catch (Exception ex)
{
logger.Debug(ex, "Writing Database Output to the text file failed");
}
finally
{
reader.Close();
outputFile.Close();
}
}
}





привет, я думаю, вы можете использовать: reader.GetName('index') например, для первого столбца: reader.GetName(0)
Подробнее по этой ссылке: https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqldatareader.getname?view=netframework-4.7.2
Добавьте переменную count, а если count == 0 добавьте имена столбцов. Похоже, вы уже знаете имена столбцов, поэтому у вас есть несколько вариантов.
Первый вариант: Просто напишите имя.
try
{
int count = 0;
while (reader.Read())
{
if (count == 0)
{
outputFile.WriteLine(String.Format("{0}, {1}, {2}",
nameOfRow0, nameOfRow1, nameOfRow2));
}
outputFile.WriteLine(String.Format("{0}, {1}, {2}",
reader[nameOfRow0], reader[nameOfRow1], reader[nameOfRow2]));
count++;
}
}
Или (если вы не знаете названия столбцов) используйте reader.GetName(i):
try
{
int count = 0;
while (reader.Read())
{
// if this is the first row, read the column names
if (count == 0)
{
outputFile.WriteLine(String.Format("{0}, {1}, {2}",
reader.GetName(0), reader.GetName(1), reader.GetName(2)));
}
// otherwise just the data (including 1st row)
outputFile.WriteLine(String.Format("{0}, {1}, {2}",
reader.GetValue(0), reader.GetValue(1), reader.GetValue(2)));
count++;
}
}
Привет, Халдо, мне очень нравятся твои подходы. Я использовал тот, где имя столбца неизвестно, потому что это делает метод более гибким. Несмотря на то, что я скопировал ваш пример (позор мне), он извлекает только имена столбцов. Есть идеи, почему?
@ fabian09 Да, у меня была ошибка в коде. Теперь исправлено - else не нужен, так как вы всегда хотите читать данные в первой строке, но вы хотите читать только имена столбцов для первой итерации. С оператором else он пропускал первую строку данных. Теперь он должен прочитать первую строку данных и прочитать имена столбцов. Дайте мне знать, если это все еще не работает.
Теперь это работает :). Еще один вопрос. Есть ли у вас какие-либо идеи, можно ли получить точный формат БД в текстовый файл? Значение: та же структура БД. Сейчас каждая строка выровнена по левому краю. Вот почему содержимое столбца не подходит к именам столбцов
@ fabian09 Это сложная задача, потому что каждый столбец может иметь разную длину. Если все столбцы разделены ,, вы можете переименовать файл, чтобы использовать расширение .csv, тогда вы можете открыть его в Excel, и столбцы/строки будут выглядеть так же, как база данных.
Хорошо. Спасибо.
мне нужно задать еще один вопрос. Дело в том, что я хочу прочитать шесть таблиц базы данных с разным количеством столбцов. Ваши предложения привязаны к трем столбцам. Если я хочу прочитать таблицу только с двумя столбцами, я получаю System.IndexOutOfRangeException: индекс был за пределами массива. Есть ли способ сделать ваш код более гибким, чтобы я мог обрабатывать разные типы таблиц с разным количеством столбцов?
@ fabian09 вы можете использовать FieldCount средства чтения данных или использовать SqlDataAdapter и DataTable вместо средства чтения данных sql. Оба эти варианта вам, вероятно, потребуются, чтобы перебрать столбцы, чтобы создать желаемый результат.
Пожалуйста, попробуйте это и установите имя строки и столбца данных в соответствии с вашими потребностями.
using (SqlConnection sqlCon = new SqlConnection("Data Source = " + GetEnvironmentVariable.MachineName + "; Initial Catalog = " + databaseName + "; User ID = " + DBUser + "; Password = " + DBUserPassword + ";"))
{
SqlCommand command = new SqlCommand(sqlQuery, sqlCon);
sqlCon.Open();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.fill(dt);
try
{
if (dt != null && dt.Rows.Count > 0)
{
string columnName = dt.Columns[0].ToString();
DataRow dr = dt.Rows[0];
}
}
catch (Exception ex)
{
logger.Debug(ex, "Writing Database Output to the text file failed");
}
finally
{
reader.Close();
outputFile.Close();
}
}
Вариант для вас: если вы используете DataAdapter и заполните DataTable, вы получите заголовки столбцов в DataTable