Oracle запрос в C # не находит совпадения на дату - PullRequest
0 голосов
/ 13 октября 2019

У меня есть две таблицы в Oracle, и я пытаюсь найти существующие записи, чтобы я мог добавить данные. Один набор данных работает, а другой - нет.

Вот таблицы (в разрезе, только с соответствующими полями)

CREATE TABLE STAGING.WEATHER_API_ACTUAL
  (
     STATIONID             VARCHAR2(4 BYTE)        NOT NULL,
     WEATHER_DATETIME      DATE                    NOT NULL,
     TEMPERATURE           NUMBER(8,2),
     (other fields, also null)
     RETRIEVAL_DATETIME    DATE)

и

CREATE TABLE STAGING.WEATHER_API_PREDICTED
   (
     STATIONID             VARCHAR2(4 BYTE)        NOT NULL,
     WEATHER_DATETIME      DATE                    NOT NULL,
     PREDICTION_DATETIME   DATE                    NOT NULL,
     HIGH_TEMP             NUMBER(8,2),
     (other fields, also null)
     RETRIEVAL_DATETIME    DATE)

Дватаблицы заполнены схожими данными, но в каждой есть дата каждый час.

WEATHER_API_ACTUAL
STATIONID          WEATHER_DATETIME              TEMPERATURE      RETRIEVAL_DATETIME
KNYC               10/12/2019 8:00:00 AM         {null}          {null}
KNYC               10/12/2019 9:00:00 AM         {null}          {null}

и

WEATHER_API_PREDICTED
STATIONID          WEATHER_DATETIME     PREDICTION_DATETIME      TEMPERATURE      RETRIEVAL_DATETIME
KNYC               10/12/2019           10/13/2019               {null}            {null} 
KNYC               10/12/2019           10/13/2019               {null}            {null}

У меня есть запросы, которые используют stationID и weather_Datetime для поиска записей и получают значения, которые являются нулевыми, и я хочу обновить их в своей базе данных,Один из запросов работает и обновляет данные. Другой не находит соответствия. Насколько я могу судить, единственное отличие состоит в том, что у человека нет временной части.

Первый запрос работает:

        static bool insertForecastWeather(string stationID, string weatherDateTime, string predictionDateTime, WeatherData weatherData, string snow)
    {
        using (OracleConnection connection = new OracleConnection(Strings.Staging_ConnectionString))
        {
            //NOTE THE TIMEZONE IS CST HARDCODED at this time.

            connection.Open();
            OracleCommand command = new OracleCommand("UPDATE Weather_API_Predicted " +
                                                "SET High_Temp = :High " +
                                                ",Low_Temp = :Low " +
                                                ",Average_Temp = :Average " +
                                                ",Wind_Speed = :WindSpeed " +
                                                ",Wind_Direction = :WindDirection " +
                                                ",Wind_Chill = :WindChill " +
                                                ",Cloud_Cover = :CloudCover " +
                                                ",Snow = :Snow " +
                                                ",Retrieval_DateTime = :RetrievalDateTime " +
                                                ",Retrieval_DateTimeTZ = 'US/Central' " +
                                                "WHERE StationID = :StationID " +
                                                "AND Weather_DateTime = to_date(:WeatherDateTime,'MM/DD/YYYY hh:mi:ss am') " +
                                                "AND Prediction_DateTime = to_date(:PredictionDateTime,'MM/DD/YYYY hh:mi:ss am')", connection);

            OracleTransaction trans = connection.BeginTransaction();
            command.Transaction = trans;

            //Values come through from the API as text values. We need to convert them to decimals first and then convert to ints to load into SQL.
            int parameterSnow = Decimal.ToInt32(Convert.ToDecimal(snow));
            string parameterWinddirection = getWindDirection(weatherData.WindDirection);

            command.Parameters.Add(new OracleParameter(":Average", weatherData.AverageTemperature));
            command.Parameters.Add(new OracleParameter(":High", weatherData.MaxTemperature));
            command.Parameters.Add(new OracleParameter(":Low", weatherData.MinTemperature));
            command.Parameters.Add(new OracleParameter(":WindSpeed", weatherData.WindSpeed));
            command.Parameters.Add(new OracleParameter(":WindDirection", parameterWinddirection));
            command.Parameters.Add(new OracleParameter(":WindChill", weatherData.WindChill));
            command.Parameters.Add(new OracleParameter(":CloudCover", weatherData.CloudCoverPercentage));
            command.Parameters.Add(new OracleParameter(":Snow", parameterSnow));
            command.Parameters.Add(new OracleParameter(":RetrievalDateTime", DateTime.Now));
            command.Parameters.Add(new OracleParameter(":StationID", stationID));
            command.Parameters.Add(new OracleParameter(":WeatherDateTime", weatherDateTime));
            command.Parameters.Add(new OracleParameter(":PredictionDateTime", predictionDateTime));
            command.ExecuteNonQuery();
            trans.Commit();

            connection.Close();
        }
        return true;
    }

На самом деле, есть еще одно отличие - этоПервый запрос использует внутреннюю таблицу weatherData. Но не для дат и станций. Это код, который не находит соответствия.

    static bool insertActualWeather(string stationID, string weatherDateTime, string temperature, string windspeed, string winddirection, string windchill, string cloudcover, string snow)
    {
        using (OracleConnection connection = new OracleConnection(Strings.Staging_ConnectionString))
        {
            //NOTE THE TIMEZONE IS CST HARDCODED at this time.

            connection.Open();
            OracleCommand command = new OracleCommand("UPDATE Weather_API_Actual " +
                                                "SET Temperature = :Temperature " +
                                                ",Wind_Speed = :WindSpeed " +
                                                ",Wind_Direction = :WindDirection " +
                                                ",Wind_Chill = :WindChill " +
                                                ",Cloud_Cover = :CloudCover " +
                                                ",Snow = :Snow " +
                                                ",Retrieval_DateTime = :RetrievalDateTime " +
                                                ",Retrieval_DateTimeTZ = 'US/Central' " +
                                                "WHERE trim(StationID) = trim(:StationID) " +
                                                "AND trunc(Weather_DateTime,'HH') = trunc(to_date(:WeatherDateTime,'MM/DD/YYYY hh:mi:ss am'),'HH') ", connection);

            OracleTransaction trans = connection.BeginTransaction();
            command.Transaction = trans;

            //Values come through from the API as text values. We need to convert them to decimals first and then convert to ints to load into SQL.
            int parameterTemperature = Decimal.ToInt32(Convert.ToDecimal(temperature));
            int parameterWindSpeed = Decimal.ToInt32(Convert.ToDecimal(windspeed));
            int parameterWindDirection = Decimal.ToInt32(Convert.ToDecimal(winddirection));
            int parameterWindChill = Decimal.ToInt32(Convert.ToDecimal(windchill));
            int parameterCloudCover = Decimal.ToInt32(Convert.ToDecimal(cloudcover));
            int parameterSnow = Decimal.ToInt32(Convert.ToDecimal(snow));

            command.Parameters.Add(new OracleParameter(":Temperature", parameterTemperature));
            command.Parameters.Add(new OracleParameter(":WindSpeed", parameterWindSpeed));
            command.Parameters.Add(new OracleParameter(":WindDirection", parameterWindDirection));
            command.Parameters.Add(new OracleParameter(":WindChill", parameterWindChill));
            command.Parameters.Add(new OracleParameter(":CloudCover", parameterCloudCover));
            command.Parameters.Add(new OracleParameter(":Snow", parameterSnow));
            command.Parameters.Add(new OracleParameter(":RetrievalDateTime", DateTime.Now));
            command.Parameters.Add(new OracleParameter(":WeatherDateTime", weatherDateTime));
            command.Parameters.Add(new OracleParameter(":StationID", stationID));
            command.ExecuteNonQuery();
            trans.Commit();
            connection.Close();
        }
        return true;
    }

Как вы можете видеть, я добавил Trim на StationID, чтобы попытаться найти совпадение, но это дата, которая, похоже, является проблемой.

Когда я запускаю его, я использую поля в таблице для получения данных из API, а затем хочу записать найденные результаты. Мой weatherDateTime - это строка "10/12/2019 8:00:00 AM" Я смотрю на возвращенные данные, и они совпадают. Но никаких записей не написано.

Если я изменю два куска кода так, чтобы строка AND WeatherData точно совпадала с той, которая работает, когда я добираюсь до ExecuteNonQuery, я получаю ошибку: ORA-01858: нечисловой символ былнашел, где ожидалось числовое значение.

Когда я смотрю эти два поля, stationID и weatherDateTime, оба раза они являются строками, они выглядят хорошо. Там нет плохих данных.

Что мне не хватает? Почему это работает для одного, а не для другого?

Ответы [ 3 ]

1 голос
/ 14 октября 2019

Обратите внимание на порядок параметров, где они используются в запросе, и где они добавляются.

В работающем запросе запрос имеет StationID, Weather_DateTime и Prediction_Datetime, а также в команде. Parameters.Add, эти поля расположены в том же порядке.

В запросе, который не работает, запрос имеет StationID и Weather_Datetime, но в command.Parameters.Add поля отображаются как Weather.Datetimeа затем StationID. Заказ должен соответствовать.

0 голосов
/ 13 октября 2019

Вы должны указать тип данных для OracleParameters. По умолчанию используется OracleDbType.Varchar2. Укажите правильное Перечисление OracleDbType

0 голосов
/ 13 октября 2019

Интересно, его 24hh:mm:ss формат, отсутствие которого вызывает несогласованные строки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...