Sto generando query SQL in Haskell e li invio a un database SQLite (3) utilizzando HDBC. Ora, questa funzione restituisce una query:Query SQL generata che non restituisce la stessa query statica corrispondente in sqlite3 HDBC
import Database.HDBC.Sqlite3
import Database.HDBC
data UmeQuery = UmeQuery String [SqlValue] deriving Show
tRunUmeQuery :: UmeQuery -> FilePath -> IO [[SqlValue]]
tRunUmeQuery (UmeQuery q args) dbFile = do
conn <- connectSqlite3 dbFile
stat <- prepare conn q
s <- execute stat args
res <- fetchAllRows' stat
disconnect conn
return $ res
selectPos targetlt parentlt op pos = let
q= "select TARGET.* from levels tl, labeltypes tlt, segments TARGET,
(select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id,
SECONDARY.label_id label_id,min(TARGET.label_id) min_childlabel_id from
levels tl, labeltypes tlt, segments TARGET, segments SECONDARY, labeltypes slt,
levels sl where TARGET.session_id = SECONDARY.session_id and ((SECONDARY.start
<= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start
and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and SECONDARY.label '
!= '' and tl.id = tlt.level_id and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id
and slt.id = SECONDARY.labeltype_id group by TARGET.session_id, TARGET.labeltype_id,
SECONDARY.label_id) SUMMARY, segments SECONDARY, labeltypes slt, levels sl where
TARGET.session_id = SECONDARY.session_id and TARGET.session_id = SUMMARY.session_id
and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start
<= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ?
and tl.id = tlt.level_id and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id =
SECONDARY.labeltype_id and SUMMARY.label_id = SECONDARY.label_id and sl.id = slt.level_id
and slt.id = SECONDARY.labeltype_id and (TARGET.label_id - SUMMARY.min_childlabel_id +1) = 2 "
a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt ]
in UmeQuery q a
che, una volta applicato al database restituisce la cosa giusta:
> let a =selectPos "Word" "Utterance" "=" 2
> let b = tRunUmeQuery a testdb
> b
uscite:
[[SqlByteString "1", SqlByteString "2", SqlByteString "3", SqlByteString "0,149383838383838", SqlByteString "0,312777777777778", SqlByteString "secondo"], [SqlByteString "1", SqlByteString "2", SqlByteString "6", SqlByteString "0,507488888888889", SqlByteString "0,655905050505051", SqlByteString "quarto"], [SqlByteString "2", SqlByteString "2", SqlByteString "3", SqlByteString "0,149383838383838", SqlByteString "0,312777777777778", SqlByteString "secondo"], [SqlByteString "2", SqlByteString "2", SqlByteString "6", SqlByteString "0,507488888888889", SqlByteString "0,655905050505051", SqlByteString "quarto"], [SqlByteString "3", SqlByteString " 2" , SqlByteString "3", SqlByteString "0,149383838383838", SqlByteString "0,312777777777778", SqlByteString "secondo"], [SqlByteString "3", SqlByteString "2", SqlByteString "6", SqlByteString "0,507488888888889", SqlByteString "0,655905050505051", SqlByteString "quarto"]]
Ora, quando ho bisogno di inserire un paio di piccole parti dinamiche nella query, come questo (mi dispiace, si deve scorrere fino alla fine della stringa da vedere questo):
selectPos targetlt parentlt op pos = let
q= "select TARGET.* from levels tl, labeltypes tlt, segments TARGET,
(select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id,
SECONDARY.label_id label_id,min(TARGET.label_id) min_childlabel_id from
levels tl, labeltypes tlt, segments TARGET, segments SECONDARY, labeltypes slt,
levels sl where TARGET.session_id = SECONDARY.session_id and ((SECONDARY.start
<= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start
and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and SECONDARY.label
!= '' and tl.id = tlt.level_id and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id
and slt.id = SECONDARY.labeltype_id group by TARGET.session_id, TARGET.labeltype_id,
SECONDARY.label_id) SUMMARY, segments SECONDARY, labeltypes slt, levels sl where
TARGET.session_id = SECONDARY.session_id and TARGET.session_id = SUMMARY.session_id
and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start
<= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ?
and tl.id = tlt.level_id and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id =
SECONDARY.labeltype_id and SUMMARY.label_id = SECONDARY.label_id and sl.id = slt.level_id
and slt.id = SECONDARY.labeltype_id and (TARGET.label_id - SUMMARY.min_childlabel_id +1) "
++ op ++ " ? "
a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt , toSql pos]
in UmeQuery q a
e fare la stessa cosa, ottengo:
> let a =selectPos "Word" "Utterance" "=" 2
> let b = tRunUmeQuery a testdb
> b
[]
Come mai la seconda query non restituisce nulla (o, la stessa cosa in realtà)?
Qualche idea?
Edit:
Ive ha studiato questo ulteriore, pensando che questo possa avere a che fare con pigro in qualche modo. Ok, l'ora è stato rimodellato per questo:
selectPos :: String -> String -> String -> Integer -> [[SqlValue]]
selectPos targetlt parentlt op pos = let
q= foldl' (++) [] ["select TARGET.* from levels tl, labeltypes tlt, segments TARGET,
(select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id,SECONDARY.label_id
label_id,min(TARGET.label_id) min_childlabel_id from levels tl, labeltypes tlt, segments
TARGET, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id "
,matchstring , " and tl.name = ? and sl.name = ? and SECONDARY.label != '' and tl.id = tlt.level_id
and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id and slt.id = SECONDARY.labeltype_id
group by TARGET.session_id, TARGET.labeltype_id, SECONDARY.label_id) SUMMARY, segments SECONDARY,
labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and TARGET.session_id =
SUMMARY.session_id " , matchstring , " and tl.name = ? and sl.name = ? and tl.id = tlt.level_id
and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id = SECONDARY.labeltype_id and SUMMARY.label_id
= SECONDARY.label_id and sl.id = slt.level_id and slt.id = SECONDARY.labeltype_id and
(TARGET.label_id - SUMMARY.min_childlabel_id +1) " , op , " ? "]
a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt , toSql (pos :: Integer)]
in UmeQuery q a
Purtroppo, questo non aiuta il problema (e quando ho: Movimento il valore di ritorno della funzione in ghci, è ancora non valutata). Quindi, la pigrizia potrebbe essere il problema in qualche modo, ma non so come farlo pienamente valutato ..? Per favore, qualche idea?
È possibile utilizzare le nuove righe in modo che il comando SQL diventi leggibile. Mostra anche l'SQL generato. –
Fatto! Per favore aiutami a capire perché queste due domande non vengono eseguite allo stesso modo. –
Dai un'occhiata alla mia risposta e fammi sapere se ho impostato qualcosa che è significativamente diverso da quello su cui stai lavorando. Onestamente non riesco a pensare ad altro. Non riesco a riprodurre un set vuoto concatenando quelle stringhe (che è essenzialmente tutto ciò che cambi). –