简体   繁体   English

C# 中的 Oracle 查询未在日期上找到匹配项

[英]Oracle query in C# not finding match on date

I have two tables in Oracle, and I'm trying to find existing records so I can add data.我在 Oracle 中有两个表,我正在尝试查找现有记录以便添加数据。 One data set works, the other does not.一个数据集有效,另一个则无效。

Here are the tables (snipped, with only the applicable fields)以下是表格(截图,只有适用的字段)

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)

and

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)

The two tables are filled with similar data, but the one has a date every hour.两张表都填满了相似的数据,但一张表每小时都有一个日期。

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}

and

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}

I have queries that use the the stationID and weather_Datetime to find records, and gets the values that are null, and I want to update them in my database.我有使用 stationID 和 weather_Datetime 查找记录的查询,并获取 null 的值,我想在我的数据库中更新它们。 One of the queries works and updates the data.其中一个查询起作用并更新数据。 The other is not finding a match.另一个是找不到匹配项。 As far as I can tell, the only difference is that one doesn't have the time part.据我所知,唯一的区别是没有时间部分。

The first query works:第一个查询有效:

        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;
    }

Actually, there is one other difference - that first query is using a internal table weatherData.实际上,还有另一个区别 - 第一个查询使用的是内部表 weatherData。 But not for the dates and stations.但不适用于日期和电台。 This is the code that does not find a match.这是找不到匹配项的代码。

    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;
    }

As you can see, I added a Trim on the StationID to try to get a match, but it's the date that appears to be the problem.如您所见,我在 StationID 上添加了 Trim 以尝试匹配,但问题似乎是日期。

When I run it, I am using the fields in the table to get the data from an API, and then want to write the results found.当我运行它时,我正在使用表中的字段从 API 中获取数据,然后想将找到的结果写入。 My weatherDateTime is a string "10/12/2019 8:00:00 AM" I'm looking at the data returned, and it's matching.我的 weatherDateTime 是一个字符串“10/12/2019 8:00:00 AM”我正在查看返回的数据,并且它是匹配的。 But no records are written.但是没有记录。

If I change the two pieces of code so the AND WeatherData line is exactly the same as the one that works, when I get to ExecuteNonQuery, I get the error: ORA-01858: a non-numeric character was found where a numeric was expected.如果我更改两段代码,使 AND WeatherData 行与有效的行完全相同,当我到达 ExecuteNonQuery 时,我收到错误:ORA-01858:在预期有数字的地方发现了一个非数字字符.

When I watch those two fields, stationID and weatherDateTime, both times they are string, they look good.当我观察这两个字段,stationID 和 weatherDateTime 时,它们都是字符串,它们看起来不错。 There isn't bad data there.那里没有坏数据。

What am I missing?我错过了什么? Why does it work for one and not the other?为什么它适用于一个而不适用于另一个?

Note the order of the parameters where they are used in the query, and where they are added.请注意在查询中使用它们的参数的顺序以及添加它们的位置。

In the query that works, the query has StationID, Weather_DateTime, and Prediction_Datetime, and in the command.Parameters.Add, those fields are in the same order.在有效的查询中,查询具有 StationID、Weather_DateTime 和 Prediction_Datetime,并且在 command.Parameters.Add 中,这些字段的顺序相同。

In the query that doesn't work, the query has StationID and Weather_Datetime, but the command.Parameters.Add, the fields are listed as Weather.Datetime and then StationID.在不起作用的查询中,查询有 StationID 和 Weather_Datetime,但在 command.Parameters.Add 中,字段被列为 Weather.Datetime,然后是 StationID。 The order needs to match.顺序需要匹配。

I wonder its 24hh:mm:ss format absence of which is causing the unmatched rows我想知道它的24hh:mm:ss格式缺失导致了不匹配的行

You should specify the data type for OracleParameters.您应该为 OracleParameters 指定数据类型。 By default OracleDbType.Varchar2 is used.默认情况下使用OracleDbType.Varchar2 Provide proper OracleDbType Enumeration提供正确的OracleDbType 枚举

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM