简体   繁体   中英

Java JDBC - invalid character, put printing query and using it in SQLDeveloper works

rootID, FSA and others are all generated earlier in the code.

PreparedStatement getPotentialParents;

        sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
                + "(SELECT * FROM("
                + "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
                + "FROM UNIQUE_CLINIC p "
                + "START WITH PARENT_ID IS NULL "
                + "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
                + "ORDER BY ROOT_ID))" + "WHERE ROOT_ID <> " + rootID + " "
                + "AND (FSA = '" + FSA + "' "
                + "OR NAME IN (" + others + ") "
                + "OR ADDRESS_1 IN (" + others + ") "
                + "OR ADDRESS_2 IN (" + others + "));";


        System.out.println(sql);


        getPotentialParents = connection.prepareStatement(sql);
        rs = getPotentialParents.executeQuery();

I get this error when this query is run, during execution: ORA-00911: invalid character

However, the printed SQL can be run on SQLDeveloper without errors:

SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM (SELECT * FROM(SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID FROM UNIQUE_CLINIC p START WITH PARENT_ID IS NULL CONNECT BY PRIOR UNIQUE_ID = PARENT_ID ORDER BY ROOT_ID))
WHERE ROOT_ID <> 10548 AND (FSA = 'null' OR NAME IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL') OR ADDRESS_1 IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL') OR ADDRESS_2 IN ('BRENNAN''S AWESOME PHARMACY #1', '38 SOLUTIONS DR', 'NULLNULLNULL'));

I'm guessing JDBC is doing something to the SQL String before querying. Any idea what might be causing this? How can I get the actual query?

I've made some updates and it's still not working, giving me an invalid character. Once again, the printed sql can be run in sqldev with no problem.:

String FSA = rs.getString("FSA");
String rootID = String.valueOf((rs.getInt("ROOT_ID")));
String others = "'" + rs.getString("NAME").replace("'", "''") + "', '" + rs.getString("ADDRESS_1").replace("'", "''") + "', '" + rs.getString("ADDRESS_2").replace("'", "''") + "'";



    Statement getPotentialParents = connection.createStatement();

    sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
            + "(SELECT * FROM("
            + "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
            + "FROM UNIQUE_CLINIC p "
            + "START WITH PARENT_ID IS NULL "
            + "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
            + "ORDER BY ROOT_ID)) " + "WHERE ROOT_ID <> " + rootID + " "
            + "AND (FSA = '" + FSA + "' "
            + "OR NAME IN (" + others + ") "
            + "OR ADDRESS_1 IN (" + others + ") "
            + "OR ADDRESS_2 IN (" + others + "));";


    System.out.println(sql);
    rs = getPotentialParents.executeQuery(sql);

You Can not use PreparedStatement like this . You have to use setString() methods to set values in qyery. otherwise user CreateStatement instead of PreparedStatement

Statement getPotentialParents;

    sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM "
            + "(SELECT * FROM("
            + "SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID "
            + "FROM UNIQUE_CLINIC p "
            + "START WITH PARENT_ID IS NULL "
            + "CONNECT BY PRIOR UNIQUE_ID = PARENT_ID "
            + "ORDER BY ROOT_ID))" + "WHERE ROOT_ID <> " + rootID + " "
            + "AND (FSA = '" + FSA + "' "
            + "OR NAME IN (" + others + ") "
            + "OR ADDRESS_1 IN (" + others + ") "
            + "OR ADDRESS_2 IN (" + others + "));";


    System.out.println(sql);


    getPotentialParents = connection.createStatement(sql);
    rs = getPotentialParents.executeQuery();

First, check that this gives the expected results in Oracle:

VARIABLE rootid   NUMBER;
VARIABLE fsa      VARCHAR2(20);
VARIABLE name     VARCHAR2(20);
VARIABLE address1 VARCHAR2(200);
VARIABLE address2 VARCHAR2(200);

BEGIN
  :rootid   := 10548;
  :fsa      := 'null';
  :name     := 'BRENNAN''S AWESOME PHARMACY #1';
  :address1 := '38 SOLUTIONS DR';
  :address2 := 'NULLNULLNULL';
END;
/

SELECT UNIQUE_ID,
       NAME,
       ADDRESS_1,
       ADDRESS_2,
       POSTAL_CODE
FROM (
  SELECT *
  FROM   (
    SELECT p.*,
           CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID
    FROM   UNIQUE_CLINIC p
    START WITH PARENT_ID IS NULL
    CONNECT BY PRIOR UNIQUE_ID = PARENT_ID
    ORDER BY ROOT_ID
  )
)
WHERE ROOT_ID <> :rootid
AND   (   FSA       = :fsa
      OR  NAME      IN ( :name, :address1, :address2 )
      OR  ADDRESS_1 IN ( :name, :address1, :address2 )
      OR  ADDRESS_2 IN ( :name, :address1, :address2 )
      );

If it does then you can just use the bind variables in Java:

(Note, you do not need the trailing ; for the query.)

String sql = "SELECT UNIQUE_ID, NAME, ADDRESS_1, ADDRESS_2, POSTAL_CODE FROM ( SELECT * FROM ( SELECT p.*, CONNECT_BY_ROOT UNIQUE_ID AS ROOT_ID FROM UNIQUE_CLINIC p START WITH PARENT_ID IS NULL CONNECT BY PRIOR UNIQUE_ID = PARENT_ID ORDER BY ROOT_ID ) ) WHERE ROOT_ID <> :rootid AND ( FSA = :fsa OR NAME IN ( :name, :address1, :address2 ) OR ADDRESS_1 IN ( :name, :address1, :address2 ) OR ADDRESS_2 IN ( :name, :address1, :address2 ) )";

PreparedStatement ps=connection.prepareStatement( sql );
OraclePreparedStatement ops = (OraclePreparedStatement) ps;
ops.setStringAtName( "fsa", rs.getString("FSA") );
ops.setIntAtName( "rootid", rs.getInt("ROOT_ID") );
ops.setStringAtName( "name", rs.getString("NAME") );
ops.setStringAtName( "address1", rs.getString("ADDRESS_1") );
ops.setStringAtName( "address2", rs.getString("ADDRESS_2") );
ps.execute();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM