使用 OleDbParameter 时无法获取值

Cannot Get Value When OleDbParameter Used

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

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

但是下面的代码块有两个问题。首先,fnam_readOk returns 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" 

这段代码有很多问题。其中之一是您使用了传递名称和 OleDbParameter 重载。 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()

基于我从 Panagiotis Kanavos 那里得到的出色回答,我更改了代码中的一个不同位置,在该位置我需要未嵌入在查询字符串中的参数。我选择使用 cmd.Parameters.Add 而不是单独的 OleDbParameter val.

(* 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