1

创建这样的查询不是很好的形式

let fnam_query =
    "select * from file_name_info where fnam_origin = 'invoice_cloud'"

但是下面的代码块有两个问题。首先, fnam_readOk 从读取中返回 false。

二、如何处置OleDbParameter?我尝试使用use,但得到一个编译时错误,说OleDbType.Char不能在使用中使用。

let fnam_query = 
    "select * from file_name_info where fnam_origin = '?' "

use fnam_cmd = new OleDbCommand(fnam_query, db_con)
let local_params = new OleDbParameter("fnam_origin", OleDbType.Char)
fnam_cmd.Parameters.Add(local_params) |> ignore

let fnam_reader = fnam_cmd.ExecuteReader ()
let fnam_readOK = fnam_reader.Read ()

let ic_lb_fnam =
    if fnam_readOK then
        fnam_reader.GetString(2)
    else
        "ic_lockbox.txt" 
4

2 回答 2

2

这段代码有很多问题。其中之一是您使用了OleDbParameter传递 name 和value的重载。该行new OleDbParameter("fnam_origin", OleDbType.Char)指定了一个参数,其名称fnam_origin和一个数值等于 的基础值OleDbType.Char

另一个问题是您根本不使用该参数。'?'只是一个包含?.

您不需要在参数化查询中引用参数。它们不是字符串替换的占位符。它们指定实际的强类型参数,就像 F# 函数参数一样。

您的查询应该是:

let fnam_query = 
"select * from file_name_info where fnam_origin = ? "

您还应该使用正确的参数类型。Char仅用于固定长度的参数。您应该使用 VarChar 甚至更好的 NVarchar。

最后,您应该传递所需的参数值。您的代码根本没有指定参数值。

整个函数应该是这样的:

let fnam_query =  "select * from file_name_info where fnam_origin = ? "
use db_con = new OleDbConnection("...")
use fnam_cmd = new OleDbCommand(fnam_query, db_con)
let local_params = new OleDbParameter("origin", SqlDbType.NVarChar,100)
fnam_cmd.Parameters.Add(local_params) |> ignore
local_params.Value <- "GR"


db_con.Open()
let fnam_reader = fnam_cmd.ExecuteReader ()
let fnam_readOK = fnam_reader.Read ()
...

但是,更好的实现是创建一次命令并使用不同的连接和值重用它:

let build_cmd = 
    let fnam_query =  "select * from file_name_info where fnam_origin = ? "
    let fnam_cmd = new OleDbCommand(fnam_query)
    let local_params = new OleDbParameter("whatever", SqlDbType.NVarChar,100)
    fnam_cmd.Parameters.Add(local_params) |> ignore
    fnam_cmd



use db_con = new OleDbConnection("...")
build_cmd.Connection <- db_con
build_cmd.Parameters.[0].Value <- "GR"
db_con.Open()
于 2017-06-19T13:28:53.130 回答
1

根据我从 Panagiotis Kanavos 得到的出色答案,我在代码中更改了一个不同的地方,在该地方我需要未嵌入查询字符串中的参数。我选择使用cmd.Parameters.Add而不是使用单独的OleDbParameterval。

(* by looking at the xfer_type, really the arg passed to main, 
we can determine the report type parameter for the Access 
database. *)
let select_report_type xfer_type =
    match xfer_type with
    | "/al" -> 0
    | "/am" -> 1
    | "/ap" -> 2
    | "/pm" -> 3
    | "/pp" -> 4
    | _     -> 99

let query = "select count(*) from ProcessStatus where ReportType = ? and ReportDate = ? and ReportFileName = ? "
use cmd = new OleDbCommand(query , db_con)
cmd.Parameters.Add(new OleDbParameter("ReportType",(OleDbType.VarChar,5))) |> ignore
cmd.Parameters.[0].Value <- ((select_report_type xfer_type).ToString())

cmd.Parameters.Add(new OleDbParameter("ReportDate",OleDbType.VarChar, 11)) |> ignore
cmd.Parameters.[1].Value <- report_date

cmd.Parameters.Add(new OleDbParameter("ReportFileName",OleDbType.VarChar, 100)) |> ignore
cmd.Parameters.[2].Value <- fn

let sql_reader = cmd.ExecuteReader ()
        if (sql_reader.Read ()) then
于 2017-06-19T16:46:08.510 回答