Uzyskiwanie wyjątku „java.sql.SQLException: wartości niezwiązane z instrukcją”

1

Niedawno zaktualizowałem z sqlite-jdbc-3.7.2.jar do sqlite-jdbc-3.26.0.jar. Zauważyłem, że zapytanie wstawiania w moim kodzie nie działa z wyjątkiem wyjątku „java.sql.SQLException: Wartości niezwiązane z instrukcją”.

Poniżej znajduje się fragment kodu, który działa dobrze dla poprzedniej wersji sqlite:

String sqlStatement = "INSERT INTO table_name(id,name,type,author,size) VALUES (?,?,?,?,?)";
try
{
    Connection conn = this.connect(<name>); 
    PreparedStatement pstmt = conn.prepareStatement(sqlStatement))
    {
        pstmt.setInt(1, rs.getInt(<value>));
        pstmt.setString(2, rs.getString(<value>));
        pstmt.setInt(3, rs.getInt(<value>));

        if (somecondition)
        {
            pstmt.setString(4, rs.getString(<Value>));
            pstmt.setInt(5, rs.getInt(<value>));

        }
        pstmt.executeUpdate();
    }
}
catch(Exception e)
{
    //handling of exception goes here
}

Przeczytałem informacje o wersji https://www.sqlite.org/changes.html i sprawdziłem, że w ramach ulepszeń Planera zapytań niewiele się zmieniło (Planista zapytań bada wartości powiązanych parametrów, aby ustalić, czy częściowe indeks jest użyteczny.). Ale nadal nie jestem pewien, jakie ulepszenie to wpłynęło na mój kod. Czy ktoś może też poprowadzić mnie, jak naprawić powyższy kod?

Dzięki, Ketaki

Ketaki Fadnavis
źródło
W łańcuchu zapytania SQL masz 5 symboli zastępczych / parametrów, ale gdy someconditionjest to fałsz, podajesz tylko 3. Na to właśnie narzeka SQLite.
Corion
Czy to twój rzeczywisty kod? Tutaj PreparedStatement pstmt = conn.prepareStatement(sqlStatement))masz dodatkowy prawy nawias, a tuż pod nim blok otoczony nawiasami klamrowymi, dlaczego? Czy brakuje instrukcji if, która nie pozwala parametrom uzyskać wartości? W każdym razie masz później taką instrukcję if.
forpas
Nie, dodatkowy wspornik jest przez pomyłkę. Oświadczenie to conn.prepareStatement (sqlStatement), ponieważ nie mogę tutaj wkleić właściwego kodu, zmodyfikowałem go nieco, a następnie wkleiłem tutaj. Proszę zignorować
Ketaki Fadnavis
Dzięki Corion. Problem został rozwiązany po przekazaniu wartości dla wszystkich kolumn. Zmodyfikowana część kodu to: if (somecondition) {pstmt.setString (4, rs.getString (<Value>)); pstmt.setInt (5, rs.getInt (<wartość>)); } else {pstmt.setString (4, <wartość domyślna>); pstmt.setInt (5, <wartość domyślna>); } Upewniłem się, że za każdym razem zapełniane są wszystkie kolumny. Dzięki za pomoc !
Ketaki Fadnavis
@Ketaki - Jeśli jest to rzeczywiście zmiana w zachowaniu w stosunku do poprzednich wersji SQLite, proszę napisać krótką odpowiedź wyjaśniającą, co trzeba zrobić, aby rozwiązać problem. Pomoże to przyszłym użytkownikom mającym ten sam problem.
Gord Thompson,

Odpowiedzi:

2

W powyższym programie zapytanie wstawiania oczekiwało, że użytkownik zapełni 5 wartości. Jeśli jednak (warunek) nie jest spełniony, wartości dla 4. i 5. nie zostały wstawione do zapytania. To był problem, ponieważ sqlite-jdbc-3.26.0 oczekuje, że wszystkie wartości zostaną wypełnione przed wykonaniem zapytania. W poprawce upewniłem się, że wszystkie wartości są wypełnione, nawet jeśli „warunek” jest fałszywy, wstawiając inny blok.

Naprawić :

 if (somecondition)
  {
            pstmt.setString(4, rs.getString(<Value>));
            pstmt.setInt(5, rs.getInt(<value>));

  }
  else
  {
            pstmt.setString(4, rs.getString(<default-value>));
            pstmt.setInt(5, rs.getInt(<defaul`enter code here`t-value>));
  }
Ketaki Fadnavis
źródło