我在haskell数据库中有表。我的' link_des'表有两列。我想同时查看两列(仅限数据)。我的代码是:
printURLs :: IO ()
printURLs = do urls <- getURLs
mapM_ print urls
getURLs :: IO [String]
getURLs = do conn <- connectSqlite3 "database.db"
res <- quickQuery' conn "SELECT * FROM link_des" []
return $ map fromSql (map head res)
有了这个,我得到第一列数据,如
[&#34; col_1_data_1&#34;,&#34; col_1_data_2&#34;,...]
使用&#39; last&#39;代替&#39; head&#39;我可以得到
[&#34; col_2_data_1&#34;,&#34; col_2_data_2&#34;,...]
但我希望得到像
这样的数据[(&#34; col_1_data_1&#34;,&#34; col_2_data_1&#34;),(&#34; col_1_data_2&#34;,&#34; col_2_data_2&#34;),...]
实际上就像模式[(row_1),(row_2),...]
任何人都可以帮助我。感谢。
答案 0 :(得分:1)
如果你看一下quickQuery的类型签名',你会看到它返回类型IO [[SqlValue]]。这意味着您已经拥有与您想要的形式非常相似的数据....而不是
[("col_1_data_1","col_2_data_1"),("col_1_data_2","col_2_data_2"), ...]
你有
[["col_1_data_1","col_2_data_1"],["col_1_data_2","col_2_data_2"], ...]
你写的函数只是使用“map head”拉出第一列。
你总是可以编写一些代码来将具有已知列数和类型的表转换为相应的元组(使用像“convert [first,second] =(fromSql first,fromSql second)”这样的函数),但它为具有不同列数和类型的任意表编写这样的东西要困难得多。这有两个原因......
一个。首先,您需要将列表转换为元组,除非您使用扩展,否则在Haskell中无法使用不同大小的列表。主要问题是元组的每个大小都是它自己的类型,并且单个函数不能根据输入选择其输出类型。你可以使用GHC扩展做一些技巧,但结果可能更复杂,你可能想要进入。
湾其次,您必须将结果中的每个值从SqlValue转换为适当的Haskell类型。出于类似的原因,这也很难。
您可能想要完全考虑另一种方法....看看Yesod持久性数据库库,它在http://www.yesodweb.com/book/persistent中描述。通过它,您可以在quasiquote中定义模式,并创建完全类型安全的Haskell记录。