У меня есть две таблицы в 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, оба раза они являются строками, они выглядят хорошо. Там нет плохих данных.
Что мне не хватает? Почему это работает для одного, а не для другого?