Проверьте, существует ли столбец при чтении базы данных на C#

В своей базе данных я создал две разные таблицы для объектов, скажем, OBJECT и ORIGINAL_OBJECT (на французском языке, например, Repere), единственная разница между ними в том, что ORIGINAL_OBJECT не имеет столбца, в котором я сохраняю сделанные изменения.

У меня есть функция, которая получает все поля:

public Repere Select_detail_repere(string query)
        {
            Repere det = null; ;
            if (this.OpenConnection() == true)
            {
                IDataReader dataReader = ExecuteReader(query);
                while (dataReader.Read())
                {
                    det = new Repere();
                    det.Name = (dataReader["DET_NOM"] ?? string.Empty).ToString().Trim();
                    det.Modifies = dataReader["MODIFICATIONS"].ToString().Trim();
                    det.Profil = (dataReader["DET_PRF"] ?? string.Empty).ToString().Trim();
                    det.Matiere = (dataReader["DET_MAT"] ?? string.Empty).ToString().Trim();
                    det.GroupeProfil = (dataReader["DET_GRP_PRF"] ?? string.Empty).ToString().Trim();
                    det.Longueur = double.Parse(dataReader["LONGUEUR"].ToString().Trim());
                    det.Largeur = double.Parse(dataReader["DET_LARGE"].ToString().Trim());
                    det.Hauteur = double.Parse(dataReader["DET_HAUT"].ToString().Trim());
                    det.Poids = double.Parse(dataReader["DET_PDS"].ToString().Trim());
                    det.Angle1 = double.Parse(dataReader["ANG_AME_1"].ToString().Trim());
                    det.Angle2 = double.Parse(dataReader["ANG_AME_2"].ToString().Trim());
                    det.AngleAile1 = double.Parse(dataReader["ANG_AILE_1"].ToString().Trim());
                    det.AngleAile2 = double.Parse(dataReader["ANG_AILE_2"].ToString().Trim());
                    det.PercageString = (dataReader["PERCAGE"] ?? string.Empty).ToString().Trim();
                    det.ScribingString = (dataReader["SCRIBING"] ?? string.Empty).ToString().Trim();
                    det.Mark = (dataReader["MARK"] ?? string.Empty).ToString().Trim();
                    det.ContInt0 = (dataReader["CONT_INT"] ?? string.Empty).ToString().Trim();
                    det.ContExt0 = (dataReader["CONT_EXT"] ?? string.Empty).ToString().Trim();
                    det.Revision = (dataReader["REVISION"] ?? string.Empty).ToString().Trim();
                }
                this.CloseConnection();
            }
            return det;
        }

Я использую одну и ту же функцию для OBJECT и OBJECT_ORIGINAL. Но когда я хочу прочитать свой OBJECT_ORIGINAL, я встречаю ошибку, в которой говорится, что поле не существует (очевидно).

Я уже встречал ту же проблему в других ситуациях, так как эта функция будет работать, только если я использую SELECT * (если я не прочитаю все столбцы, это вернет ошибку).

До сих пор я нашел единственный способ решить эту проблему - использовать try / catch (в уловке я буду применять значение по умолчанию, например, ID=-1), но я чувствую, что это не очень правильное решение, и ищу другой способ сделать что.

Вы читали документацию MSDN для IDataReader?

ArieKanarie 27.10.2018 09:22

только что сделал это сейчас, но это не помогло ...

Siegfried.V 27.10.2018 10:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
443
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Было бы полезно указать в качестве запроса, который вы используете, но я думаю, что вы можете использовать IF COL_LENGTH('table_name','column_name') IS NOT NULL в своем запросе.

Запрос очень простой: SELECT * FROM table1 будет работать, SELECT * FROM table2 не будет работать, поскольку столбец «MODIFICATIONS» не существует. Мне нужно поставить условие не в запросе, а когда я читаю результат

Siegfried.V 27.10.2018 09:08

Вы можете использовать хранимую процедуру mysql и выполнять внутри нее проверку. проверьте это здесь. проверьте, существует ли столбец перед ALTER TABLE - mysql

Я уже видел это, и это не то, что я хочу, то, что он говорит в этом посте, - создать столбец, если он не существует, и я не хочу трогать его.

Siegfried.V 27.10.2018 09:03

Ах, извините, что не поняла. Его тихие конфиденциальные манипуляции с базой данных, ага ..

jayromel lawas 27.10.2018 10:35
Ответ принят как подходящий

Вам нужно проверить, существует ли столбец MODIFICATIONS в устройстве чтения данных, поскольку вы не знаете его заранее.

В документация Microsoft я нашел метод под названием GetSchemaTable.
Это даст вам таблицу данных, которая описывает метаданные столбца. Таким образом, вы можете проверить эту таблицу, чтобы увидеть, есть ли столбец с именем MODIFICATIONS.
Я бы поставил эту проверку другим методом, чтобы она не сильно загромождала код в вашем цикле while.

ИЛИ

Вы можете проверить этот вопрос на StackOverflow Проверьте имя столбца в объекте SqlDataReader, у которого есть более короткое решение вашей проблемы. Я думаю, что это еще более приятное и простое решение, но я нашел его (с помощью простого поиска в Google) после того, как почти завершил свой ответ выше. Вот почему я даю вам оба решения (а также немного помогу вам с документацией MS, на которую я указал в своем комментарии)

Хорошо, думаю, я понял. С помощью метода, указанного в ссылке на стек, я запускаю метод «HasColumn» (разумеется, только один раз), затем ifelse решит проблему.

Siegfried.V 27.10.2018 14:41

Что касается ссылки на стек, я не смог понять, как она работает. Но благодаря вам я нашел ссылку на GetSchemaTable, затем на DataColumnCollection, и я думаю, что нашел что-то, это не так "коротко", как я ожидал, но это помогает, спасибо

Siegfried.V 27.10.2018 18:55

Этот вопрос можно цитировать как "Повторяющийся", я нашел ответ на куча

public Repere Select_detail_repere(string query)
{
    Repere det = null; ;
    if (this.OpenConnection() == true)
    {
        IDataReader dataReader = ExecuteReader(query);
        bool containsModification = CheckIfDataContains(dataReader, "MODIFICATIONS");
        while (dataReader.Read())
        {
            det = new Repere();
            det.Name = (dataReader["DET_NOM"] ?? string.Empty).ToString().Trim();
            if (containsModification)
            {
                 det.Modifies = dataReader["MODIFICATIONS"].ToString().Trim();
            }
            else
            {
                 det.Modifies = "";
            }
            det.Profil = (dataReader["DET_PRF"] ?? string.Empty).ToString().Trim();
            det.Matiere = (dataReader["DET_MAT"] ?? string.Empty).ToString().Trim();
            ...
         }
         this.CloseConnection();
      }
      return det;
  }
  public bool CheckIfDataContains(IDataReader dataReader,string columnName)
    {
        for (int i = 0; i < dataReader.FieldCount; i++)
        {
            if (dataReader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
            return true;
        }
        return false;
    }

Мне нравится. Вместо использования цикла for вы используете метод contains, который просматривает все столбцы. Вы можете сократить метод, просто выполнив return columns.Contains(columnName) вместо оператора if, но это как раз то, что вам нравится.

ArieKanarie 29.10.2018 09:08

спасибо, на самом деле return columns.Contains (columnName) лучше, только что отредактировал, спасибо за ваш отзыв. p.S: как вы "седеете" свои комментарии?

Siegfried.V 29.10.2018 12:26

Для этого вы можете использовать обратные кавычки, см. stackoverflow.com/editing-help#code для справки по форматированию.

ArieKanarie 29.10.2018 12:39

Ну просто "непринятый" ответ, как я заметил только сейчас, код не работает, на самом деле {columns.Contains (columnName)} всегда возвращает false

Siegfried.V 31.10.2018 10:20
Contains может быть чувствительным к регистру. Также убедитесь, что имена столбцов не повторяются, он вернет false. См. Документацию Microsoft
ArieKanarie 31.10.2018 10:32

все еще ищу, на данный момент все мои имена столбцов - «ColumnName», «ColumnOrdinal», «ColumnSize» и т.д., кажется, я читаю определение столбцов вместо их имен.

Siegfried.V 31.10.2018 14:36

Хорошо, нашел, мой код неправильный, и нашел ответ в стеке, сейчас отредактирую свой ответ

Siegfried.V 31.10.2018 14:42

Хорошо, что теперь работает. Я вижу, что вы закончили с кодом, упомянутым в ссылке, которую я опубликовал в своем ответе stackoverflow.com/questions/373230/… (что нормально)

ArieKanarie 31.10.2018 14:59

В самом деле? это ссылка, которую вы мне дали? (только что проверил, и это ...) ну, тогда я сделал это очень плохо, не знаю, почему я помню, я смотрел вашу ссылку и ничего не понял ... или я прочитал действительно плохо, или за это время я понял что-то получше, кто знает ... в любом случае спасибо за помощь Ура (тогда ваш ответ будет хорошим, пока они не укажут мой вопрос как дубликат ^^)

Siegfried.V 31.10.2018 15:03

Другие вопросы по теме