[英]Insert Database Haskell
我有一个类似的列表: [["a","b"],["c","d"],["e","f"]]
,即(row1, row2, row3)
我要插入数据。 我的代码是
store xs =
do conn <- connectSqlite3 "ld.db"
stmt <- prepare conn "INSERT INTO ld (url, des) VALUES (?,?)"
executeMany stmt [(head (map (\x -> [toSql x]) xs) ++ last (map (\x -> [toSql x]) xs))]
commit conn
如果我单独使用store ["a","b"]
。 但是我无法像store [["a","b"],["c","d"],["e","f"]]
那样插入。 我尝试了几种方法,但是失败了。 我们需要正确使用map
。 谢谢。
这将工作-
let values = [["a", "b"], ["c", "d"], ["e", "f"]]
sequence $ map store values
或者,您可以使用更直观的-
forM values store
它的工作方式类似于命令循环的Haskell版本。 可以将其想像Java / c / javascript之类的伪代码:
for(value in values)
{
store(value);
}
您将必须导入Control.Monad。
话虽如此,您可能想重构它。...您正在为每个插入创建连接,这可能会降低性能(只需将connectSqlite3和commit行从函数中拉出,并将conn作为参数传递)。
我正在编辑以对类型进行一些讨论,以便您可以更好地了解这里发生的情况。
store ["a", "b"]
是IO()类型。...这是main想要的,因此您已设置好。
map store values
类型为[IO()],需要先转换为IO()才能在main中使用。 在某种程度上,任何Haskell程序的全部目的都是生成一个IO(),main可以使用它来修改世界(输入和输出)。 如果将这些列表递给main,则不知道要使用哪个列表。
sequence
是一种函数,它将IO()的列表并将它们“排序”成一个单独的IO(),可由main使用。 (对于高级人员,我知道,它实际上适用于任何monad,但我认为这可能会混淆事情)。
forM
只是对序列的友好重写,并带有移动的参数。
此代码有两个问题:
缺少正确的导入(用于转换的Database.HDBC.SqlValue)
单行的存储类型不能与多行的存储类型相同。
改进的代码:
module Main(main) where
import Database.HDBC.Sqlite3
import Database.HDBC
import Database.HDBC.Types
import Database.HDBC.SqlValue
import Data.Convertible.Base
storeOne :: [String] -> IO ()
storeOne xs =
do conn <- connectSqlite3 "ld.db"
stmt <- prepare conn "INSERT INTO ld (url, des) VALUES (?,?)"
execute stmt $ map toSql xs
commit conn
storeMany :: [[String]] -> IO ()
storeMany xs =
do conn <- connectSqlite3 "ld.db"
stmt <- prepare conn "INSERT INTO ld (url, des) VALUES (?,?)"
executeMany stmt $ map (map toSql) xs
commit conn
main = do storeOne ["a", "b"]
storeMany [["a","b"],["c","d"],["e","f"]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.