我有一种情况,我要获取一个SQL查询和SQL参数(以避免SQL注入)作为输入。
我正在使用下面的代码使用VoltDB的AdHoc
存储过程来运行该SQL。
private static final String voltdbServer = "localhost";
private static final int voltdbPort = 21212;
public ClientResponse runAdHoc(String sql, Object... sqlArgs) throws IOException, ProcCallException
{
ClientConfig clientConfig = new ClientConfig();
Client voltdbClient = ClientFactory.createClient(clientConfig);
voltdbClient.createConnection(voltdbServer, voltdbPort);
return voltdbClient.callProcedure("@AdHoc", sql, sqlArgs);
}
但是我收到错误消息org.voltdb.client.ProcCallException: SQL error while compiling query: Incorrect number of parameters passed: expected 2, passed 1
对于runAdHoc("select * from table where column1 = ? and column2 = ?", "column1", "column2")
,当有两个或多个参数时。
我收到错误org.voltdb.client.ProcCallException: Unable to execute adhoc sql statement(s): Array / Scalar parameter mismatch ([Ljava.lang.String; to java.lang.String)
对于runAdHoc("select * from table where column1 = ?", "column1");
,只有一个参数。
但是当我直接致电voltdbClient.callProcedure("@AdHoc", "select * from table where column1 = ? and column2 = ?", "column1", "column2")
我认为VoltDb不能将sqlArgs
视为单独的参数,而是将它们视为一个数组。
解决此问题的一种方法是自己解析SQL字符串,然后将其传递,但我发布此消息是为了了解解决此问题的有效方法。
注意:-使用的SQL只是测试SQL
答案 0 :(得分:1)
@Adhoc系统过程正在将数组识别为一个参数。 @Adhoc会发生这种情况,因为没有计划要进行的过程,在哪里可以明确说明每个参数是什么。
您具有将sqlArgs数组解析为实际参数以单独传递的正确想法。您也可以将这些单独的参数连接到SQL语句本身中。这样,您的即席声明将简单地是:
voltdbClient.callProcedure("@AdHoc", sql)
完全公开:我在VoltDB工作。
答案 1 :(得分:0)
我在VoltDB公共备用频道上发布了相同的问题,得到了一个解决以下问题的答复:
简短的解释是,您需要将@Adhoc
的参数转换为[sql, sqlArgs]
。您需要创建一个新数组[sql, sqlArg1, sqlArg2, …]
,将sqlArgs.length + 1
放在位置0,然后将sql
复制到新数组中,从位置1开始。然后将该新构造的数组传递到致电sqlArgs
所以我如下修改了client.callProcedure("@AdHoc", newArray)
方法,它解决了这个问题
runAdHoc