Я генерирую SQL-запросы в Haskell и отправляю их в базу данных SQLite (3) с использованием HDBC. Теперь эта функция возвращает запрос:Сгенерированный SQL-запрос не возвращает то же самое, что и соответствующий статический запрос в 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
, который, когда применяются к базе данных возвращает правильную вещь:
> 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", SqlByteString "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", SqlByteString "0,149383838383838", SqlByteString "0,312777777777778", SqlByteString "второй"], [SqlByteString "3", SqlByteString "2", SqlByteString "6", SqlByteString "0,507488888888889", SqlByteString «+0,655905050505051», SqlByteString «четвёртый»]]
Теперь, когда мне нужно вставить пару небольших динамических частей в запрос, как это (извините, у вас есть, чтобы перейти к концу строки в увидеть это):
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
[]
Почему второй запрос ничего не возвращает (или, фактически, на самом деле)?
Любые идеи?
Edit:
Ive исследовал этот вопрос дальше, думая, что это, возможно, придется делать с ленивым каким-то образом. Хорошо, теперь изменили к этому:
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
К сожалению, это не помогает этот вопрос (и когда я: Спринт возвращаемое значение функции в GHCI, он по-прежнему невычисленного). Итак, лень может быть проблемой как-то, но я не знаю, как сделать это полностью оцененным ..? Пожалуйста, какие-нибудь идеи?
Возможно, вы захотите использовать символы новой строки, чтобы команда SQL стала читаемой. Также покажите сгенерированный SQL. –
Сделано! Пожалуйста, помогите мне понять, почему эти два запроса не выполняются одинаково. –
Взгляните на мой ответ и сообщите мне, если я установлю что-то, существенно отличающееся от того, над чем вы работаете. Я честно не могу думать ни о чем другом. Я не могу воспроизвести пустой набор, объединив эти строки (что по существу все, что вы меняете). –