代码之家  ›  专栏  ›  技术社区  ›  Philosopher

将变量传递到SOQL中的select查询中

  •  3
  • Philosopher  · 技术社区  · 8 年前

    我正在运行一个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代码中允许绑定变量。下面,您可以看到我尝试用简单的salesforce格式为SOQL查询运行的查询。

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

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

    2 回复  |  直到 8 年前
        1
  •  7
  •   Luke Woodward    8 年前

    @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时,无法像简单的Salesforce那样使用参数化SOSQL。如果我们想在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自己的服务器上运行。

        2
  •  0
  •   harfel    8 年前

    我没有使用简单的salesforce包的经验,但看看您的代码,我想知道答案是否没有那么简单

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

    即,输入 价值 将myString的 名称 .