Я генерирую SQL-запросы в Haskell и отправляю их в базу данных SQLite(3) с помощью 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
который при применении к базе данных возвращает правильную вещь:
> let a =selectPos "Word" "Utterance" "=" 2
> let b = tRunUmeQuery a testdb
> b
выходы:
[[SqlByteString "1", SqlByteString "2", SqlByteString "3", SqlByteString "0.149383838383838", SqlByteString "0.312777777777778", SqlByteString "второй"], [SqlByteString "1", SqlByteString "2", SqlByteString "6", "0,507488888888889", SqlByteString "0.655905050505051", SqlByteString "четвертое"], [SqlByteString "2", SqlByteString "2", SqlByteString "3", SqlByteString "0.149383838383838", SqlByteString "0.312777777777778", SqlByteString "второй"], [SqlByteString " 2", SqlByteString "2", SqlByteString "6", SqlByteString "0,507488888888889", SqlByteString "0,655905050505051", SqlByteString "четвертый"], [SqlByteString "3", SqlByteString "2", SqlByteString "3", Sql838String "808.38String" SqlByteString "0.31277777777778", SqlByteString "второй"], [SqlByteString "3", SqlByteString "2", SqlByteString "6", SqlByteString "0.507488888888889", SqlByteString "0.655905050505051", SqlByteString] "fourth"
Теперь, когда мне нужно вставить в запрос пару небольших динамических частей, например так (извините, вам нужно прокрутить строку до конца, чтобы увидеть это):
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
и делаю то же самое, я получаю:
> let a =selectPos "Word" "Utterance" "=" 2
> let b = tRunUmeQuery a testdb
> b
[]
Почему второй запрос ничего не возвращает (или то же самое)?
Любые идеи?
Редактировать:
Я исследовал это дальше, думая, что это может быть как-то связано с ленью. Хорошо, теперь это было изменено на это:
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
К сожалению, это не решает проблему (и когда я :sprint возвращаю значение функции в ghci, оно все еще не оценивается). Итак, лень может быть проблемой, но я не знаю, как это полностью оценить..? Пожалуйста, есть идеи?