使用 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
创建这样的查询不是很好的形式
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