Kwerenda z opcjonalnym null'em

0

Chodzi o sięganie z Javy do baz SQL. Użyję nazwanych parametrów (więc lepiej niż na JDBC). Parametr może być - lub może go nie być, null, pusty, bez selekcji, weź wszystko
Przypuszczalna implementacja na JDBI

query = "select * from invoices where date ... and invoices.customerId = :cust"
..setParameter(":cust" , someCustomer)

to wiadomo jak działa

i żeby ta kwerenda się automatycznie przekonfigurowała dla wszystkich

..setParameter(":cust" , null)

Tu ma zgromadzić wszystko w dziedzinie czasu, z wszystkich customerów

Kombinuję ale mam spore wątpliwości. Ma nie rzucać wyjątkami javowskimi, ma nie zabijać wydajności kwerendy itd...
"select * from invoices where date ... and (invoices.customerId = :cust or :cust is null)"
albo łatwiejsze
"select * from invoices where date ... and (invoices.type = :tp or :tp='*' )"

W starszym soluszynie string kwerendy był warunkowo sklejany (z parametrami, spoko, nie krzyczcie) na oba warunki, zachciało mi się ładniej

0
Ziemiak napisał(a):

Cos w tym stylu? https://stackoverflow.com/a/51160628

Odnajduję tam te same pomysły, czyli jakby nie są one niebezpieczne / totalnie głupie

(swoją drogą w JDBC numer kolejny powinni dać nazwane parametry, bo te pytajniki to epoka brązu)

0

Będzie ciężko i pod wiatr, bo null w SQL i Javie to nie jest to samo pojęcie. Pomysły z tego linka na SO są niebezpiecznie blisko SQL injection.

Teoretycznie da się napisać taką kwerendę:
select * from tabelka where coalesce(jakieś_pole, wartość_zastępcza) = coalesce(:parametr, wartość_zastępcza) ale to dla odmiany walnie w wydajność, chyba, że pod tę kwerendę założy się indeks funkcyjny.

0

Czemu niby podatne na SQL injection skoro parametry sa podawane w params a nie wbite na pałe w SQL

0

@Ziemiak: Nie napisałem, ze jest podatna, tylko jest blisko takiej podatności. Sklejanie zapytania z danych wejściowych jest brzydkie, bo zawsze jest szansa, ze coś przeoczysz.

0
piotrpo napisał(a):

@Ziemiak: Nie napisałem, ze jest podatna, tylko jest blisko takiej podatności. Sklejanie zapytania z danych wejściowych jest brzydkie, bo zawsze jest szansa, ze coś przeoczysz.

Ciąg myślenia idzie "odejść od sklejania" na zrecz "zrobić to sprytnie"

W podanych SO rzeczywiście jest i sklejanie, by dojść do niesklejanych

0

Co powiecie na taki wzorzec oparty na wieloliniowym stringu (tu w formie nowoczesnej javy)
Realnie w życiu się sprawdza, wzorzec chodzi to od lat w C#

Jak się widzi pod wzgledem elegancji

String _query = """select * from AlaMaKota 
join ... 
where date >= ... 
  [ and customerId = : cust ]
and vat != 0 ... itd
order ...grop by ...
"""

for(String line : _query)
   {
       if(line.Trim().StartWith("[") && coś z dwukropkiem jest w dictionary null )
   }

0

@ZrobieDobrze: IMO nie wygląda to zbyt dobrze. Jeśli już faktycznie chcesz zrobić to tak, żeby było przyjemne dla oka to przykryj to jakimś builderem.

0
wartek01 napisał(a):

@ZrobieDobrze: IMO nie wygląda to zbyt dobrze. Jeśli już faktycznie chcesz zrobić to tak, żeby było przyjemne dla oka to przykryj to jakimś builderem.

Z szacunkiem, ale to MA BYĆ jak najdalsze od budowania kwerend w języku. To ma być wklejenie sprawdzonej w SQL Studio, PgAdminie itd kwerendy plus jak najbardziej kosmetyczne zmiany, zrozumiałem dla SQLowca.

A zaciekawiłeś mnie na poziomie teoretycznym. To taki builder ujemny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1