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

C# .NET OleDbCommand操作DB2/400时SUBSTRING函数报错SQL0104

问题描述

我正在开发一个连接IBM i平台上DB2/400数据库的REST API,当前使用以下连接字符串建立数据库连接:

//  Defaut connexion string           
ConnectString = "Provider=IBMDA400;" + "Password=xxxxxxx;" +"User ID=Bxxxxxxxx;" +"Data Source=XXX.XX.XX.XX;";

数据库连接功能正常,连接代码如下:

ConnectLst = new OleDbConnection(ConnectString);
try
{
    ConnectLst = new OleDbConnection(ConnectString);

    ConnectLst.Open();

    ResCnx = true;
}
catch (Exception ex)
{
    ResCnx = false;
}

finally
{ }

return ResCnx;

但执行包含子串截取的SQL查询时出现语法错误,查询语句如下:

string W_RqtSql = "SELECT SUBSTRING(CDMATN,2,3) " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = '" + @_NumPers + "'";

收到的错误信息:

SQL0104: Syntactic element ,2 is not correct. Possible elements: , FROM.
Cause . . . . .: A syntax error was detected at element ,2. , 2 is not a valid element. , FROM is a partial list of valid elements.

尝试使用SUBSTR函数也无法正常运行,但去掉截取函数的相同查询可以正常执行:

string W_RqtSql = "SELECT CDMATN " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = '" + @_NumPers + "'";

需要解决如何实现对列值的子串查询。

解决方案

1. 使用ODBC标量函数语法适配OLE DB驱动

IBMDA400驱动在处理函数时,需要用ODBC标准的{fn ...}语法包裹函数,这样驱动才能正确解析并转换为DB2/400支持的语法:

string W_RqtSql = "SELECT {fn SUBSTRING(CDMATN, 2, 3)} " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = '" + @_NumPers + "'";

或者用SUBSTR的ODBC写法:

string W_RqtSql = "SELECT {fn SUBSTR(CDMATN, 2, 3)} " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = '" + @_NumPers + "'";

2. 直接使用DB2/400原生SUBSTR语法

如果上述方法无效,尝试DB2/400原生的子串函数写法,确保参数格式正确:

string W_RqtSql = "SELECT SUBSTR(CDMATN, 2, 3) AS SUB_CDMATN " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = '" + @_NumPers + "'";

给截取结果加别名可以方便后续代码处理返回值。

3. 必须修复SQL注入风险

当前代码用字符串拼接构造SQL语句,存在严重的SQL注入漏洞,建议改用参数化查询:

string W_RqtSql = "SELECT {fn SUBSTRING(CDMATN, 2, 3)} " +                
                 " FROM " + @_Schema + ".CSALAR CSAL " +                     
                 " where CSAL.NOPPHN = ?";

using (OleDbCommand cmd = new OleDbCommand(W_RqtSql, ConnectLst))
{
    cmd.Parameters.AddWithValue("@NumPers", _NumPers);
    // 执行查询、读取结果的逻辑
}

参数化查询不仅能避免注入攻击,还能解决特殊字符导致的语法错误。

内容的提问来源于stack exchange,提问作者Jchristophe Cherid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:56:14