1

我正在尝试运行此查询,但出现错误

ORA-00907: 缺少右括号

我查看了声明,但括号是正确的。我删除了最后一行查询,它可以工作:

AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL ? MINUTE)

也许可以是 '>' 运算符中的东西,但没有它我不能这样做。

代码:

String sql= "SELECT DID.ORDER_ID "
            + "FROM TEST_ORDER DID, TEST_ORDER_SG DOS, TEST_HRD_SHIPS_GRP DHSG, TEST_INFO CSI "
            + "WHERE DID.ORDER_ID = DOS.ORDER_ID "
            + "AND DOS.SHIPPING_GROUPS = DHSG.SHIPPING_ID "
            + "AND DOS.SHIPPING_GROUPS = CSI.SHIPPING_ID "
            + "AND DHSG.TRACKING_CODE IS NULL AND CSI.SHIPPING_CARRIER IN "
            + "(?) "
            + "AND DID.STATE IN (?) "
            + "AND NOT EXISTS "
            + "("
            + "SELECT 1 FROM "
            + "CLIENT_INTEGRATION.TEST_LOG_ORDERS_STATUS TN "
            + "WHERE TN.ORDER_ID = DID.ORDER_ID AND TN.STATE = DID.STATE "
            + "AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL ? MINUTE)"
            + ")";

绑定参数的代码:

int actualIndex = 0;
for (int i = 0; i < params.length; i++) {
    actualIndex = sql.indexOf('?', actualIndex+1);
    Class classe = params[i].getClass();

    if(classe.isArray()) {
        StringBuffer newPlaceHolders = new StringBuffer();

        int arrayLength = java.lang.reflect.Array.getLength(params[i]);

        for (int j = 0; j < arrayLength; j++) {

            if (j>0) {
                newPlaceHolders.append(",?");                        
            } else {
                newPlaceHolders.append("?");                        
            }
        }

        sql = sql.substring(0, actualIndex) + newPlaceHolders + sql.substring(actualIndex+1);
        actualIndex += newPlaceHolders.length();
    }

    if (actualIndex == -1) {
           break;
    }
}

因此,在另一种方法中,我填充了一些 for 循环,因为在某些情况下,参数(位于属性文件中)可能不止一个。

int i=1;
    for(String carriers : getCarrier()) {
        ps.setString(i, carriers);              
        i++;
    }

    for(String state : getAllStates()) {
        ps.setString(i, state);
        i++;
    }
4

3 回答 3

3

INTERVAL ? MINUTE无效。

语法是INTERVAL '1' MINUTE(并且您不能为该值指定变量)。

如果要指定需要使用的变量TO_DSINTERVAL()

就像是:

TO_DSINTERVAL( '0 00:' || TO_CHAR( ?, 'FM00' ) || ':00' )

旁白

您似乎通过修改查询以采用多个绑定变量将列表传递到查询中;你不需要这样做。相反,您可以将 Oracle 集合作为单个绑定变量传入。可以在这里找到一个示例(稍微复杂一点,因为该示例用于多维数组),但这里有一个更简单的示例

于 2016-06-27T14:25:19.337 回答
0

子查询中子句的最终条件WHERE应如下所示:

AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL '10' MINUTE)

您需要将时间量放在单引号中。

于 2016-06-27T14:25:54.207 回答
0

使用intervalor的更简单的解决方案to_dsinterval()是使用直接日期算术。您可以在日期时间或时间戳中添加或减去数字;该数字以天为单位,因此如果您的输入(显示为?)以分钟为单位,则必须除以 24*60。像这样:

... and tn.last_update > current_timestamp - ? / 24 * 60

请注意,这会将右侧更改为日期/时间(无小数秒),因此如果您需要小数秒,它将不起作用。

于 2016-06-27T15:11:10.147 回答