首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SQL错误:执行预准备语句时DB2代码=-302

SQL错误:执行预准备语句时DB2代码=-302
EN

Stack Overflow用户
提问于 2019-06-11 03:40:56
回答 2查看 1.8K关注 0票数 0

我有一个接受用户输入的SQL查询,因此存在安全缺陷。

现有查询为:

代码语言:javascript
复制
SELECT  BUS_NM, STR_ADDR_1, CITY_NM, STATE_CD, POSTAL_CD, COUNTRY_CD,
        BUS_PHONE_NB,PEG_ACCOUNT_ID, GDN_ALERT_ID, GBIN, GDN_MON_REF_NB,
        ALERT_DT, ALERT_TYPE, ALERT_DESC,ALERT_PRIORITY 
FROM ( SELECT A.BUS_NM, AE.STR_ADDR_1, A.CITY_NM, A.STATE_CD, A.POSTAL_CD,
              CC.COUNTRY_CD,  A.BUS_PHONE_NB, A.PEG_ACCOUNT_ID, 'I' || 
              LPAD(INTL_ALERT_DTL_ID, 9,'0') GDN_ALERT_ID, 
              LPAD(IA.GBIN, 9,'0') GBIN, IA.GDN_MON_REF_NB,
              DATE(IAD.ALERT_TS) ALERT_DT, 
              XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing  
                IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE, 
              , ROW_NUMBER() OVER () AS "RN" 
       FROM ACCOUNT A, Other tables 
       WHERE IA.GDN_MON_REF_NB = '100'  
         AND A.PEG_ACCOUNT_ID = IAAR.PEG_ACCOUNT_ID  
         AND CC.COUNTRY_CD = A.COUNTRY_ISO3_CD 
       ORDER BY IA.INTL_ALERT_ID ASC )  
WHERE  ALERT_TYPE  IN (" +TriggerType+ ");

我将其更改为接受来自setString的TriggerType,如下所示:

代码语言:javascript
复制
SELECT BUS_NM, STR_ADDR_1, CITY_NM, STATE_CD, POSTAL_CD, COUNTRY_CD,
       BUS_PHONE_NB,PEG_ACCOUNT_ID, GDN_ALERT_ID, GBIN, GDN_MON_REF_NB,
       ALERT_DT, ALERT_TYPE, ALERT_DESC,ALERT_PRIORITY 
FROM ( SELECT A.BUS_NM, AE.STR_ADDR_1, A.CITY_NM, A.STATE_CD, A.POSTAL_CD, 
              CC.COUNTRY_CD,  A.BUS_PHONE_NB, A.PEG_ACCOUNT_ID, 
              'I' || LPAD(INTL_ALERT_DTL_ID, 9,'0') GDN_ALERT_ID,
              LPAD(IA.GBIN, 9,'0') GBIN, IA.GDN_MON_REF_NB, 
              DATE(IAD.ALERT_TS) ALERT_DT, 
              XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing  
                IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE, 
              ROW_NUMBER() OVER () AS "RN" 
       FROM ACCOUNT A, other tables 
       WHERE IA.GDN_MON_REF_NB = '100'  
         AND A.PEG_ACCOUNT_ID = IAAR.PEG_ACCOUNT_ID   
         AND CC.COUNTRY_CD = A.COUNTRY_ISO3_CD 
       ORDER BY IA.INTL_ALERT_ID ASC )  
WHERE  ALERT_TYPE  IN (?);

触发器类型设置如下:

代码语言:javascript
复制
if (StringUtils.isNotBlank(request.getTriggerType())) {
   preparedStatement.setString(1, triggerType != null ? triggerType.toString() : "");
}

获取错误为

原因: com.ibm.db2.jcc.am.SqlDataException: DB2 SQL错误: SQLCODE=-302,SQLSTATE=22001,SQLERRMC=null,DRIVER=4.19.26

EN

回答 2

Stack Overflow用户

发布于 2019-06-11 05:29:26

-302SQLCODE表示某种类型的转换错误。

可以说,DB2不会把30磅的垃圾塞进一个4磅的袋子里,它会给你一个错误。也许在转换过程中给XML一些额外的空间可能会有所帮助。如果您需要确保它最终只有4个字符,您可以显式地执行一个LEFT(XMLCAST( ... AS VARCHAR(64)), 4)。这样,XMLCAST就有了所需的空间,但您可以将其缩减以适应fetch上的变量。

另一件事可能是传递给参数标记的变量太长。DB2将根据ALERT_TYPE的长度猜测类型和长度。请注意,您只能通过参数标记传递单个值。如果您传递一个逗号分隔的列表,它的行为将不会像预期的那样(除非您希望ALERT_TYPE也包含一个逗号分隔的列表)。

票数 0
EN

Stack Overflow用户

发布于 2019-06-12 01:45:07

与参数一起使用的IN谓词错误。

不要期望IN ('AAAA, M250, ABCD') (当您尝试将逗号分隔的字符串作为单个参数传递时)像IN ('AAAA', 'M250', 'ABCD')一样工作(根据您的需要)。这些谓词是不等价的。

如果你想像下面这样传递一个逗号分隔的字符串,你需要一些“字符串标记器”。

代码语言:javascript
复制
select t.*
from
(
select XMLCAST(XMLQUERY('$A/alertTypeConfig/biqCode/text()' passing IAC.INTL_ALERT_TYPE_CONFIG as "A") AS CHAR(4)) ALERT_TYPE
from table(values xmlparse(document '<alertTypeConfig><biqCode>M250, really big code</biqCode></alertTypeConfig>')) IAC(INTL_ALERT_TYPE_CONFIG)
) t
--WHERE  ALERT_TYPE IN ('AAAA, M250, ABCD')
join xmltable('for $id in tokenize($s, ",\s?") return <i>{string($id)}</i>' 
passing cast('AAA, M250 , ABCD' as varchar(200)) as "s" 
columns token varchar(200) path '.') x on x.token=t.ALERT_TYPE
;

按原样运行该语句。然后,您可以取消对字符串with WHERE子句的注释,并注释掉其余的子句,看看您想要做什么。

附言:

您得到的错误可能是因为您没有指定参数的数据类型(您没有使用类似于IN (cast(? as varchar(xxx)))的数据类型,并且db2编译器假定它的长度等于ALERT_TYPE表达式的长度(4字节)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56532611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档