如何使用 SQL 格式的动态 where 子句制作谓词

Posted

技术标签:

【中文标题】如何使用 SQL 格式的动态 where 子句制作谓词【英文标题】:How to make predicate with dynamic where clause of SQL format 【发布时间】:2019-09-03 15:49:58 【问题描述】:

我对正在开发的企业应用程序有一个需求,该应用程序将 SQL 查询存储在系统中。

例如:

    WORKTYPE not in('PM','PM1','EV','OP')

    :worktype <>'PM' AND :worktype <>'PM1' AND :worktype <>'EV' AND :worktype <>'OP'

WORKTYPE n :worktype 是实体的属性

PM、PM1、EV、OP是要过滤的值

================================================ =========================

这些是我必须在 NSPredicate 中处理的 where 子句的一些示例。

编程语言:Swift 4

数据库:Coredata

关于如何处理这些表达式的任何建议?

【问题讨论】:

显示到目前为止您已经尝试过的内容。你有什么问题?你知道如何创建一个简单的NSPredicate吗?复合谓词呢? 仅供参考 - 示例 1 和 2 相同。 @rmaddy 我想做这样的事情 NSPredicate(format: "WORKTYPE not in('PM','PM1','EV','OP')") 是的,示例 1 和 2 都相同。这些查询 where 子句可以以我获取之前未知的任何格式编写 您是否调查过使用NSExpression 动态构建谓词以匹配您的查询? 【参考方案1】:

您可以在运行时创建 NSPredicate,并在最后使用 NSCompoundPredicate 组合谓词。就像下面的语法一样

let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1, predicate2])

【讨论】:

【参考方案2】:

顺便说一句 - 我同意 cmets - 你应该在你的问题中提供更多信息并解释你尝试过的内容,包括代码尝试等......但是失败了......

从 Apple 开发者文档中了解 NSExpression 类...

NSExpression

用于比较谓词的表达式。

概览

NSPredicate 中的比较操作基于两个表达式,由 NSExpression 类的实例表示。 为常量值、键路径等创建表达式。

虽然它是一个存档文档,但 Apple 的“Predicate Programming Guide”仍然适用于在 Swift 和 Objective-C 中使用带有 Core Data 的谓词的人。我建议你阅读它。

在本文档中,我特别指出...

Creating Predicates > Creating Predicates Using Predicate Templates

文档中的示例(翻译成 Swift)...

以下示例使用格式字符串创建谓词 右侧是变量表达式。

let predicateTemplate = NSPredicate(format: "lastName like[c] %@", argumentArray: [$LAST_NAME])

这相当于直接创建变量表达式为 如下例所示。

let lhs = NSExpression(forKeyPath: "lastName"]
let rhs = NSExpression(forVariable: "LAST_NAME"]

let comparisonPredicate = NSComparisonPredicate(leftExpression: lhs, 
                                                rightExpression: rhs, 
                                                modifier: .direct, 
                                                type: .like, 
                                                options: [.caseInsensitive])

讲座和你的问题已经讲完了......

WORKTYPE 不在('PM','PM1','EV','OP')

我在这里假设您具备解析 SQL 表达式以提取下面前两行代码中列出的信息的知识。

let keyPath: String = "WORKTYPE"
let arrayWorkTypes: [String] = ["PM", "PM1", "EV", "OP"]

var arrayComparisonPredicates = [NSPredicate]()

for workType in arrayWorkTypes 

    let expressionLHS = NSExpression(forKeyPath: keyPath)
    let expressionRHS = NSExpression(forConstantValue: workType)
    let comparisonPredicate = NSComparisonPredicate(leftExpression: expressionLHS,
                                                    rightExpression: expressionRHS,
                                                    modifier: .direct,
                                                    type: .notEqualTo,
                                                    options: [.caseInsensitive])

     arrayComparisonPredicates.append(comparisonPredicate)
 

 let andPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: arrayComparisonPredicates)

以这种方式动态构建您的andPredicate,您应该能够成功运行您的获取请求。

我还没有测试过这段代码,所以请告诉我你的情况,我会在必要时更新。

最后...您的数据库不是核心数据。

如果您在 Xcode 项目中使用 Core Data 框架,您的数据库很可能是 SQLite。

简单地说,根据***,Core Data 是“一个模型对象图和持久性框架......”

我强烈建议您阅读和阅读,然后再阅读,直到您真正理解其中的区别。我保证这将是您宝贵的时间投资。

【讨论】:

以上是关于如何使用 SQL 格式的动态 where 子句制作谓词的主要内容,如果未能解决你的问题,请参考以下文章

如何使用带有复合 WHERE 子句的 DataGrip SQL 格式化程序

如何在sql中创建动态where子句?

可以将绑定变量连接到动态 SQL WHERE 子句以添加 AND 语句吗?

如何在 SQL 的 WHERE 子句中动态调用列

如何在 SQL 查询中动态跳过没有 If else 的 where 子句?

如何将字符串变量传递给动态sql中的where子句