You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DevExpress升级后GetOracleWhere方法加引号致Oracle SQL错误求助

DevExpress升级后Oracle查询引号问题解决方案

代码片段

if (!String.IsNullOrEmpty(filterColumns))
{
    filterColumns = filterColumns.Replace("[", "[lower(").Replace("]", ")]");
    CriteriaOperator op = CriteriaOperator.Parse(filterColumns);
    string filter = String.Empty;
    if (dbUtils.DbType == 1)
    {
        filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, false);
        filter = filter.ToLower();
    }
}

问题描述

这段C#代码在旧版DevExpress中运行正常,升级后GetOracleWhere方法生成的查询会给lower(templatename)强制添加双引号,导致Oracle SQL报错。生成的SQL示例如下:

SELECT COUNT(*) dataCount  
FROM (SELECT r.* 
      FROM rmrtemplate r
      WHERE templatename IS NOT NULL AND (instr("lower(templatename)", '0022') > 0)) tmptable

问题核心:被双引号包裹的"lower(templatename)"会被Oracle识别为字符串而非SQL函数,进而抛出无效标识符错误,问题由filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, false);这一行引发。

当前GetOracleWhere的可用重载:

public static string GetOracleWhere(CriteriaOperator op);
public static string GetOracleWhere(CriteriaOperator op, bool forceQuotesOnOperandProperties);
public static string GetOracleWhere(CriteriaOperator op, Func<OperandProperty, string> propertyFormatter);

曾尝试用正则和字符串替换移除引号,但未生效:

filter = Regex.Replace(filter, "\"(lower\\(templatename\\))\"", "$1"); // 尝试移除lower(templatename)周围的引号
filter = filter.Replace("\"", ""); // 尝试移除所有剩余引号

可行解决办法

方法1:使用带propertyFormatter的重载(推荐)

利用第三个重载自定义属性格式化逻辑,从根源上避免给包含SQL函数的表达式添加引号:

if (dbUtils.DbType == 1)
{
    filter = CriteriaToWhereClauseHelper.GetOracleWhere(op, operandProperty => {
        // 若属性名称包含lower(,直接返回原表达式,不添加引号
        if (operandProperty.PropertyName.Contains("lower("))
        {
            return operandProperty.PropertyName;
        }
        // 正常属性按需处理,这里保留默认加引号的逻辑(可根据实际调整)
        return $"\"{operandProperty.PropertyName}\"";
    });
    filter = filter.ToLower();
}

方法2:修正正则替换逻辑

如果坚持用字符串替换,调整正则表达式匹配通用的lower(...)格式,同时忽略大小写:

// 匹配所有被双引号包裹的lower(...)表达式,忽略大小写
filter = Regex.Replace(filter, "\"(lower\\([^)]+\\))\"", "$1", RegexOptions.IgnoreCase);
// 移除剩余不必要的引号
filter = filter.Replace("\"", "");

方法3:用DevExpress API构建函数表达式

避免手动拼接lower(字符串,改用FunctionOperator构建函数条件,让DevExpress正确识别SQL函数:

if (!String.IsNullOrEmpty(filterColumns))
{
    // 示例:构建lower(templatename)包含'0022'的查询条件
    var property = new OperandProperty("templatename");
    var lowerFunction = new FunctionOperator(FunctionOperatorType.Lower, property);
    var criteria = new FunctionOperator(FunctionOperatorType.Contains, lowerFunction, "0022");
    
    string filter = String.Empty;
    if (dbUtils.DbType == 1)
    {
        filter = CriteriaToWhereClauseHelper.GetOracleWhere(criteria);
        filter = filter.ToLower();
    }
}

内容的提问来源于stack exchange,提问作者Natnael Haile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 19:15:13