如何在fsharp.data.sqlclient中使用SQL IN语句?

14

我有以下示例代码。目标是使用多个输入参数运行SQL语句。

[<Literal>]
let connectionString = @"Data Source=Localhost;Initial Catalog=Instrument;Integrated Security=True"
[<Literal>]
let query = "SELECT MacroName, MacroCode FROM Instrument WHERE MacroCode IN (@codeName)"

type MacroQuery = SqlCommandProvider<query, connectionString>
let cmd = new MacroQuery()
let res = cmd.AsyncExecute(codeName= [|"CPI";"GDP"|]) |> Async.RunSynchronously

然而,codeName被推断为字符串类型,而不是数组或列表,并给我带来了错误。

或者,我可以在没有where语句的情况下运行查询,并基于结果进行过滤。 然而,在许多其他返回数百万行的情况下,我更喜欢在SQL服务器级别过滤数据以提高效率。

我在fsharp.data.sqlclient的文档中没有找到任何相关示例。请帮忙!


我假设你的目标是SQL Server。那么,它不使用数组或列表的原因很简单 - SQL Server没有这样的数据类型。它有一个专门设计用于存储多个数据项的数据类型 - 表格。我对[fsharp.data.sqlclient]不太熟悉,但我建议你尝试找出如何向其传递表值参数。 - Damien_The_Unbeliever
3个回答

6

8
所以你必须将查询放入存储过程中,并创建一个自定义的SQL类型才能使用IN语句?太麻烦了。 - Joel Mueller

4
如果您在IN列表中的值上有一个上限n,您可以只创建n个参数。如果这仍然难以管理,恐怕TVP建议是最佳选择。FSharp.Data.SqlClient库很可能永远不会直接支持此功能,因为类型是基于从sp_describe_undeclared_parameters获得的结果生成的;没有T-SQL解析器。在这种情况下,我们的上限为一位数字,我们不愿更改数据库,所以这个选项对我们有效。

2
您可以使用STRING_SPLIT来抽象出表值参数的使用。似乎您还需要先声明该参数。
DECLARE @param varchar(1000) = @commaSeparatedList
SELECT Col1 FROM MyTable
WHERE Col2 IN (
  SELECT value FROM STRING_SPLIT(@param, ',')
)

这很酷,但请注意,STRING_SPLIT需要兼容级别130,即SQL Server 2016最低版本。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接