繁体   English   中英

插入数据库Haskell

[英]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

只是对序列的友好重写,并带有移动的参数。

此代码有两个问题:

  1. 缺少正确的导入(用于转换的Database.HDBC.SqlValue)

  2. 单行的存储类型不能与多行的存储类型相同。

改进的代码:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM