【问题标题】:Pass a variable into a select query in SOQL将变量传递到 SOQL 中的选择查询中
【发布时间】:2016-02-10 21:40:00
【问题描述】:

我正在运行一个 Python 脚本,该脚本使用 simple-salesforce package 来查询我的 Salesforce 帐户中的所有数据。对于上下文,脚本读取存储在 CSV 文件中的字典,并将特定值(即字符串)存储在变量中(见下文)。

    with open('/Users/username/Documents/filename.csv', 'rU') as f:
        mydict = dict(filter(None, csv.reader(f)))
    myString = mydict['key']

然后,我想将变量 (myString) 传递到 SOQL 选择查询中。但是,当我尝试将变量传递到查询中时,我收到以下错误:绑定变量只允许在 Apex 代码中。下面,您可以看到我尝试以 simple-salesforce 的格式运行 SOQL 查询的查询。

    sf.query("SELECT Id, Name FROM deal__c WHERE contact__c = myString")

我的问题是:如何将我的变量传递给 SOQL 选择查询?如果这是最佳解决方案,我愿意使用 Apex 或 Dynamic SOQL,但如果这是最佳解决方案,请告知如何在我的 Python 脚本中使用 Apex 代码(即,如果我需要指定切换到 Apex 或安装 Apex 的位置不知何故)。

【问题讨论】:

    标签: python apex soql


    【解决方案1】:

    @harfel 的答案很接近,但它的引号是错误的,因为 SOQL 中的字符串文字必须用单引号括起来。

    这是解决问题的第一次尝试:

    # What happens if myString is "John O'Groats"?
    sf.query("SELECT Id, Name FROM deal__c WHERE contact__c = '%s'" % myString)
    

    虽然 Salesforce 的专有语言 Apex 支持参数化 SOQL,但在通过 REST API 调用 Salesforce 时无法像 simple-salesforce 那样使用参数化 SOQL。如果我们想在 SOQL 查询中使用未知值,字符串连接是我们唯一的选择。

    但是,如果我们要将字符串值连接到 SOQL 查询中,我们必须“转义”任何保留字符以避免 SOQL 注入。 Salesforce 文档对此非常清楚:只有两个 reserved characters:反斜杠 \ 和单引号 '。将转义字符串值的函数如下:

    def soqlEscape(someString):
        # Escape backslashes and single-quotes, in that order.
        return someString.replace("\\", "\\\\").replace("'", "\\'")
    

    我们可以使用这个函数来更好地解决问题:

    sf.query("SELECT Id, Name FROM deal__c WHERE contact__c = '%s'" % soqlEscape(myString))
    

    或者,如果您知道contact__c 参数的值永远只能是字母数字,那么您可以预先验证该值而不是转义它:

    if myString.isalnum():
        # Value is alphanumeric, safe to concatenate in.
        sf.query("SELECT Id, Name FROM deal__c WHERE contact__c = '%s'" % myString)
    else:
        raise ValueError("Invalid contact__c: '%s'" % myString)
    

    “安装”Apex 不是一种选择:它只能在 Salesforce 自己的服务器上运行。

    【讨论】:

    • 为什么要换成'\\'?它应该是'\'对吗?它应该以一个'\'而不是'\\'开头,对吧?
    • @rajkris: "\\" 显示为.replace 的第一个参数,因为 Python 将反斜杠解释为转义字符以及 Apex。 "\\" 是一个包含单个反斜杠的 Python 字符串,"\\\\" 是一个包含两个反斜杠的 Python 字符串。 ("\" 是 Python 中的语法错误,r"\" 也是如此。)
    【解决方案2】:

    我没有使用 simple-salesforce 包的经验,但是看看你的代码,我想知道答案可能没有那么简单

    sf.query('SELECT Id, Name FROM deal__c WHERE contact__c = "%s"' % myString)
    

    即在查询中输入 myString 的 value 而不是其name

    【讨论】:

    • 一定要使用你的数据库版本的prepared statements而不是直接的字符串值,以避免SQL注入漏洞。
    • @harfel 我试过你的建议。它返回一个错误:在字符 \'"\'' 处没有可行的替代方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    相关资源
    最近更新 更多