Haskell runtime error : UnsuccessfulReturnCode "odbc_SQLExecDirectW" (-1)
Haskell runtime error : UnsuccessfulReturnCode "odbc_SQLExecDirectW" (-1)
目前我正在编写一个运行几个 SQLServer 查询的小程序。为了使查询类型保存,我创建了一个模块“SQLQuery”,它可以让您以保存的方式设计查询。
要执行查询,它们必须是 Query 类型,因此我做了以下操作...
toSql $
T.pack (show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC)))
我的 Main.hs 代码是...
{-# LANGUAGE OverloadedStrings #-}
import Database.ODBC.SQLServer
import Data.ByteString
import qualified Data.Text as T
import SQLQuery (AND (..), Column (..), Direction (..), FROM (..),
GROUPBY (..), ORDERBY (..), Operand (..),
Operator (..), SELECT (..), Table (..), WHERE (..),
condition)
main :: IO ()
main = do
conn <- connectToDB
selectGipscommDB conn
clients <- queryClients conn
selectClientDB conn
orders <- queryOrders conn
print clients
print orders
-- Produces valid sql string (tested!)
print $ show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC))
close conn
connectToDB :: IO Connection
connectToDB =
connect
"DRIVER={ODBC Driver 13 for SQL Server};SERVER=xxx;Uid=yyy;Pwd=zzz"
selectGipscommDB :: Connection -> IO ()
selectGipscommDB =
flip exec gipscommDB
gipscommDB :: Query
gipscommDB =
"USE abc"
type Client = ByteString
queryClients :: Connection -> IO [Client]
queryClients =
flip query clientsSql
clientsSql :: Query
clientsSql =
toSql $ T.pack (show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC)))
-- "SELECT name FROM kundenDBs WHERE activeProdData = 'true' ORDER BY name"
type Product = ByteString
type Order = ByteString
queryOrders :: Connection -> IO [(Product, Order)]
queryOrders = flip query ordersSql
ordersSql :: Query
ordersSql =
"SELECT artikelnummer, auftrag FROM ProdData_ WHERE artikelnummer <> '' AND auftrag <> '' GROUP BY auftrag, artikelnummer ORDER BY artikelnummer"
selectClientDB :: Connection -> IO ()
selectClientDB =
flip exec clientDB
clientDB :: Query
clientDB =
"USE xyz"
我的 SQLQuery 模块代码是...
{-# LANGUAGE OverloadedStrings #-}
module SQLQuery where
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import Data.String (IsString (fromString))
import qualified Data.Text as T
import Database.ODBC.SQLServer
-- SELECT
--
data SELECT
= SELECT [Column] FROM WHERE GROUPBY ORDERBY
instance Show SELECT where
show (SELECT cols from where' groupBy orderBy) =
"SELECT " ++ join ", " cols ++ " " ++ show from ++ " " ++ show where' ++ " " ++ show groupBy ++ " " ++ show orderBy
-- FROM
--
newtype FROM = FROM Table
instance Show FROM where
show (FROM tbl) = "FROM " ++ show tbl
-- WHERE
--
data WHERE
= WHERE [AND]
| NothingW
instance Show WHERE where
show (WHERE ands) = "WHERE " ++ join " AND " ands
show NothingW = ""
-- AND
--
newtype AND = AND Condition
instance Show AND where
show (AND cond) = show cond
--GROUPBY
--
data GROUPBY
= GROUPBY [Column]
| NothingGB
instance Show GROUPBY where
show (GROUPBY cols) = "GROUP BY " ++ join ", " cols
show NothingGB = ""
-- ORDERBY
--
newtype ORDERBY = ORDERBY [Column]
instance Show ORDERBY where
show (ORDERBY cols) = "ORDER BY " ++ join ", " cols
-- Table
--
newtype Table = Table String
instance Show Table where
show (Table tbl) = tbl
-- Column
--
data Column = Column String Direction
instance Show Column where
show (Column col dir) = col ++ " " ++ show dir
-- Condition
--
data Condition
= Condition Operand Operator Operand
instance Show Condition where
show (Condition operand1 operator operand2) = show operand1 <> show operator <> show operand2
condition :: String -> Operator -> String -> Condition
condition operand1 operator operand2 =
Condition (Operand operand1) operator (Operand operand2)
-- Operand
--
newtype Operand = Operand String
instance Show Operand where
show (Operand operand) = operand
-- Operator
--
data Operator
= Eq
| Ueq
| Gt
| Lt
instance Show Operator where
show Eq = " = "
show Ueq = " <> "
show Gt = " > "
show Lt = " < "
-- Direction
--
data Direction
= ASC
| DESC
instance Show Direction where
show ASC = "ASC"
show DESC = "DESC"
-- Functions
--
join :: Show a => String -> [a] -> String
join str = intercalate str . map show
哪个类型检查但在运行时导致错误...
UpdateProdData-exe.EXE: UnsuccessfulReturnCode "odbc_SQLExecDirectW" (-1) "[Microsoft][ODBC
Driver 13 for SQL Server][SQL Server]In EXECUTE <procname>, procname can only be a literal or
variable of type char, varchar, nchar, or nvarchar.[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]In EXECUTE <procname>, procname can only be a literal or variable of type char,
varchar, nchar, or nvarchar."
嗯,我不知道如何解决这个问题,如果有人能帮助我,我将不胜感激。 :)
Haskell ODBC 库旨在进行字符串转义。似乎正在发生的是 toSql "String"
将字符串的内容包装为转义的 SQL 字符串,而不是未转义的查询。
如果您使用 fromString myQuery
而不是 toSQL $ T.pack myQuery
,它应该可以工作。
目前我正在编写一个运行几个 SQLServer 查询的小程序。为了使查询类型保存,我创建了一个模块“SQLQuery”,它可以让您以保存的方式设计查询。
要执行查询,它们必须是 Query 类型,因此我做了以下操作...
toSql $
T.pack (show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC)))
我的 Main.hs 代码是...
{-# LANGUAGE OverloadedStrings #-}
import Database.ODBC.SQLServer
import Data.ByteString
import qualified Data.Text as T
import SQLQuery (AND (..), Column (..), Direction (..), FROM (..),
GROUPBY (..), ORDERBY (..), Operand (..),
Operator (..), SELECT (..), Table (..), WHERE (..),
condition)
main :: IO ()
main = do
conn <- connectToDB
selectGipscommDB conn
clients <- queryClients conn
selectClientDB conn
orders <- queryOrders conn
print clients
print orders
-- Produces valid sql string (tested!)
print $ show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC))
close conn
connectToDB :: IO Connection
connectToDB =
connect
"DRIVER={ODBC Driver 13 for SQL Server};SERVER=xxx;Uid=yyy;Pwd=zzz"
selectGipscommDB :: Connection -> IO ()
selectGipscommDB =
flip exec gipscommDB
gipscommDB :: Query
gipscommDB =
"USE abc"
type Client = ByteString
queryClients :: Connection -> IO [Client]
queryClients =
flip query clientsSql
clientsSql :: Query
clientsSql =
toSql $ T.pack (show (SELECT [Column "name"] (FROM (Table "kundenDBs")) (WHERE [AND (condition "activeProdData" Eq "'true'")]) NothingGB (ORDERBY [Column "name"] ASC)))
-- "SELECT name FROM kundenDBs WHERE activeProdData = 'true' ORDER BY name"
type Product = ByteString
type Order = ByteString
queryOrders :: Connection -> IO [(Product, Order)]
queryOrders = flip query ordersSql
ordersSql :: Query
ordersSql =
"SELECT artikelnummer, auftrag FROM ProdData_ WHERE artikelnummer <> '' AND auftrag <> '' GROUP BY auftrag, artikelnummer ORDER BY artikelnummer"
selectClientDB :: Connection -> IO ()
selectClientDB =
flip exec clientDB
clientDB :: Query
clientDB =
"USE xyz"
我的 SQLQuery 模块代码是...
{-# LANGUAGE OverloadedStrings #-}
module SQLQuery where
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import Data.String (IsString (fromString))
import qualified Data.Text as T
import Database.ODBC.SQLServer
-- SELECT
--
data SELECT
= SELECT [Column] FROM WHERE GROUPBY ORDERBY
instance Show SELECT where
show (SELECT cols from where' groupBy orderBy) =
"SELECT " ++ join ", " cols ++ " " ++ show from ++ " " ++ show where' ++ " " ++ show groupBy ++ " " ++ show orderBy
-- FROM
--
newtype FROM = FROM Table
instance Show FROM where
show (FROM tbl) = "FROM " ++ show tbl
-- WHERE
--
data WHERE
= WHERE [AND]
| NothingW
instance Show WHERE where
show (WHERE ands) = "WHERE " ++ join " AND " ands
show NothingW = ""
-- AND
--
newtype AND = AND Condition
instance Show AND where
show (AND cond) = show cond
--GROUPBY
--
data GROUPBY
= GROUPBY [Column]
| NothingGB
instance Show GROUPBY where
show (GROUPBY cols) = "GROUP BY " ++ join ", " cols
show NothingGB = ""
-- ORDERBY
--
newtype ORDERBY = ORDERBY [Column]
instance Show ORDERBY where
show (ORDERBY cols) = "ORDER BY " ++ join ", " cols
-- Table
--
newtype Table = Table String
instance Show Table where
show (Table tbl) = tbl
-- Column
--
data Column = Column String Direction
instance Show Column where
show (Column col dir) = col ++ " " ++ show dir
-- Condition
--
data Condition
= Condition Operand Operator Operand
instance Show Condition where
show (Condition operand1 operator operand2) = show operand1 <> show operator <> show operand2
condition :: String -> Operator -> String -> Condition
condition operand1 operator operand2 =
Condition (Operand operand1) operator (Operand operand2)
-- Operand
--
newtype Operand = Operand String
instance Show Operand where
show (Operand operand) = operand
-- Operator
--
data Operator
= Eq
| Ueq
| Gt
| Lt
instance Show Operator where
show Eq = " = "
show Ueq = " <> "
show Gt = " > "
show Lt = " < "
-- Direction
--
data Direction
= ASC
| DESC
instance Show Direction where
show ASC = "ASC"
show DESC = "DESC"
-- Functions
--
join :: Show a => String -> [a] -> String
join str = intercalate str . map show
哪个类型检查但在运行时导致错误...
UpdateProdData-exe.EXE: UnsuccessfulReturnCode "odbc_SQLExecDirectW" (-1) "[Microsoft][ODBC
Driver 13 for SQL Server][SQL Server]In EXECUTE <procname>, procname can only be a literal or
variable of type char, varchar, nchar, or nvarchar.[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]In EXECUTE <procname>, procname can only be a literal or variable of type char,
varchar, nchar, or nvarchar."
嗯,我不知道如何解决这个问题,如果有人能帮助我,我将不胜感激。 :)
Haskell ODBC 库旨在进行字符串转义。似乎正在发生的是 toSql "String"
将字符串的内容包装为转义的 SQL 字符串,而不是未转义的查询。
如果您使用 fromString myQuery
而不是 toSQL $ T.pack myQuery
,它应该可以工作。