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
相关产品推荐
相关产品推荐

