sql语法错误,但级联文本在Datagrip中运行良好

时间:2019-10-24 12:30:21

标签: java postgresql intellij-idea

我正在尝试运行查询,但是在运行查询时出现错误。

但是,我正在使用Intellij,并且当我使用复制字符串串联到剪贴板功能并在datagrip中运行查询时,查询运行良好(在输入参数之后)

我得到的错误是“错误:“ tstoredarticle”或附近的语法错误\ n位置:199“

在tstoredartiacle之后显示行有变化,我觉得有点奇怪,但除此之外,我看不出有什么问题。

哪些问题可能导致类似的问题?

我在intellij中的查询如下:

    private ResultSet getHuaweiSqlQuery(Integer intBrandID, Integer intStorageID, Vector<Integer> vecArticleTypes, int iCurrencyID, int iContactSupplierID, int secondaryStorage, BigDecimal exchangeRate) throws SQLException {
        return Hibernate3To4Utils.getConnection(session).createStatement().executeQuery("SELECT storedarticleid, "
                + " CASE WHEN storedarticle_storageid = " + intStorageID
                + " THEN id_storedarticleid_replacement ELSE"
                + " (SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)"
                + " FROM etel.tstoredarticle x"
                + " WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid"
                + " AND x.storedarticle_storageid = " + intStorageID + ")"
                + " END as id_storedarticleid_replacement,"
                + " articlename,"
                + " articledescription, CASE WHEN price IS NULL THEN last_innprice*" + exchangeRate
                + " ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,"
                + " amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location"
                + " FROM etel.tstoredarticle"
                + " INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid"
                + " LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid"
                + " AND ((tusedarticle.datesnap >= CAST(now() as date)-" + LOOK_BACK_DAYS
                + " AND usedarticlefromstorage = true) OR waiting = true)"
                + " LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = " + Constants.SERVICEPLACE
                + " LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid"
                + " AND tsupplier_price.id_serviceplaceid = " + Constants.SERVICEPLACE
                + " AND tsupplier_price.id_currencyid = " + iCurrencyID
                + " AND tsupplier_price.id_contactid_supplier = " + iContactSupplierID
                + " LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid"
                + " AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where"
                + " latest_usedarticle.usedarticle_storedarticleid = storedarticleid)"
                + " WHERE storedarticle_storageid IN(" + intStorageID + ", " + secondaryStorage + ") AND b.id_brandid = " + intBrandID
                + " AND id_articletypeid IN (" + getStringFromArray(vecArticleTypes.toArray()) + ")"
                + " AND tstoredarticle.passive <> true"
                + " GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],"
                + " storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap"
                + " ORDER BY id_storedarticleid_replacement, storedarticleid");
    }

,这是使用复制字符串串联到剪贴板功能后的相同查询: (运行正常)

SELECT storedarticleid, 
 CASE WHEN storedarticle_storageid = ?
 THEN id_storedarticleid_replacement ELSE
 (SELECT COALESCE(id_storedarticleid_replacement, storedarticleid)
 FROM etel.tstoredarticle x
 WHERE tstoredarticle.storedarticle_articleid = x.storedarticle_articleid
 AND x.storedarticle_storageid = ?)
 END as id_storedarticleid_replacement,
 articlename,
 articledescription, CASE WHEN price IS NULL THEN last_innprice*?
 ELSE price END as last_innprice, id_modelids[1] as order_modelid, storedarticleamount-amount_in_order-amount_waiting as disponibelt,
 amount_in_order, amount_in_bestilling, sum(tusedarticle.amount) as ant_artikler, articleid,amount_waiting, location
 FROM etel.tstoredarticle
 INNER JOIN etel.tarticle as b ON storedarticle_articleid = b.articleid
 LEFT JOIN etel.tusedarticle ON usedarticle_storedarticleid = storedarticleid
 AND ((tusedarticle.datesnap >= CAST(now() as date)-42
 AND usedarticlefromstorage = true) OR waiting = true)
 LEFT JOIN etel.torder ON usedarticle_orderid = orderid AND torder.id_serviceplaceid = ?
 LEFT JOIN etel.tsupplier_price ON id_articleid = b.articleid
 AND tsupplier_price.id_serviceplaceid = ?
 AND tsupplier_price.id_currencyid = ?
 AND tsupplier_price.id_contactid_supplier = ?
 LEFT JOIN etel.tusedarticle as last_used on storedarticleid = last_used.usedarticle_storedarticleid
 AND last_used.usedarticleid = (select MAX(latest_usedarticle.usedarticleid) from etel.tusedarticle as latest_usedarticle where
 latest_usedarticle.usedarticle_storedarticleid = storedarticleid)
 WHERE storedarticle_storageid IN(?, ?) AND b.id_brandid = ?
 AND id_articletypeid IN (?)
 AND tstoredarticle.passive <> true
 GROUP BY storedarticleid,id_storedarticleid_replacement, articlename, articledescription, last_innprice, id_modelids[1],
 storedarticleamount, amount_in_order, amount_in_bestilling, articleid,price,amount_waiting, location, last_used.datesnap
 ORDER BY id_storedarticleid_replacement, storedarticleid

1 个答案:

答案 0 :(得分:1)

请勿将字符串与动态文本值结合使用来构建SQL语句。

例如,如果文本值是由用户提供的,则您很容易受到SQL injection攻击,从而使黑客能够窃取您的数据并删除表。

但是在正确引用和转义文本值方面也遇到了问题。

相反,请使用PreparedStatement,在需要动态值的任何地方放置?标记。那是剪贴板中的字符串。

示例:您正在做

String name = "John";
String sql = "SELECT * FROM Person WHERE name = " + name;

这会在运行时为您提供此文本:

SELECT * FROM Person WHERE name = John

这是错误的,因为文本值需要用引号引起来:

SELECT * FROM Person WHERE name = 'John'

您可以尝试

String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = '" + name + "'";

但是这也是错误的,因为这个新的文本值嵌入了引号,并且会产生:

SELECT * FROM Person WHERE name = 'John's Cross'

为正确起见,请使用PreparedStatement

String name = "John's Cross";
String sql = "SELECT * FROM Person WHERE name = ?";

PreparedStatement stmt = Hibernate3To4Utils.getConnection(session).prepareStatement(sql);
stmt.setParameter(1, name);
return stmt.executeQuery();

JDBC驱动程序将处理所有需要的转义操作,从而保护您免受SQL注入攻击和SQL语法错误的侵害。