提交 2e80129d authored 作者: Thomas Mueller's avatar Thomas Mueller

CallableStatement: now the syntax "{? = CALL...}" is supported as well.

上级 9c32f47a
...@@ -138,6 +138,7 @@ import org.h2.value.ValueDate; ...@@ -138,6 +138,7 @@ import org.h2.value.ValueDate;
import org.h2.value.ValueDecimal; import org.h2.value.ValueDecimal;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
import org.h2.value.ValueNull;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
...@@ -283,6 +284,15 @@ public class Parser { ...@@ -283,6 +284,15 @@ public class Parser {
} else { } else {
char first = token.charAt(0); char first = token.charAt(0);
switch (first) { switch (first) {
case '?':
// read the ? as a parameter
readTerm();
// this is an 'out' parameter - set a dummy value
parameters.get(0).setValue(ValueNull.INSTANCE);
read("=");
read("CALL");
c = parseCall();
break;
case '(': case '(':
c = parseSelect(); c = parseSelect();
break; break;
......
...@@ -53,6 +53,29 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call ...@@ -53,6 +53,29 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements Call
setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id); setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id);
} }
/**
* Executes an arbitrary statement. If another result set exists for this
* statement, this will be closed (even if this statement fails). If auto
* commit is on, and the statement is not a select, this statement will be
* committed.
*
* @return true if a result set is available, false if not
* @throws SQLException if this object is closed or invalid
*/
public boolean execute() throws SQLException {
try {
checkClosed();
if (command.isQuery()) {
super.executeQuery().next();
return true;
}
super.executeUpdate();
return false;
} catch (Exception e) {
throw logAndConvert(e);
}
}
/** /**
* Executes a statement (insert, update, delete, create, drop) * Executes a statement (insert, update, delete, create, drop)
* and returns the update count. * and returns the update count.
......
...@@ -1195,7 +1195,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1195,7 +1195,7 @@ public class JdbcConnection extends TraceObject implements Connection {
level--; level--;
break; break;
} else if (chars[i] == '?') { } else if (chars[i] == '?') {
chars[i++] = ' '; i++;
checkRunOver(i, len, sql); checkRunOver(i, len, sql);
while (Character.isSpaceChar(chars[i])) { while (Character.isSpaceChar(chars[i])) {
i++; i++;
...@@ -1204,7 +1204,7 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1204,7 +1204,7 @@ public class JdbcConnection extends TraceObject implements Connection {
if (sql.charAt(i) != '=') { if (sql.charAt(i) != '=') {
throw DbException.getSyntaxError(sql, i, "="); throw DbException.getSyntaxError(sql, i, "=");
} }
chars[i++] = ' '; i++;
checkRunOver(i, len, sql); checkRunOver(i, len, sql);
while (Character.isSpaceChar(chars[i])) { while (Character.isSpaceChar(chars[i])) {
i++; i++;
...@@ -1368,11 +1368,11 @@ public class JdbcConnection extends TraceObject implements Connection { ...@@ -1368,11 +1368,11 @@ public class JdbcConnection extends TraceObject implements Connection {
return; return;
} }
if (session != null && openStackTrace != null) { if (session != null && openStackTrace != null) {
trace.error("Connection not closed", openStackTrace); trace.error(openStackTrace, "connection not closed");
try { try {
close(); close();
} catch (SQLException e) { } catch (SQLException e) {
trace.debug("finalize", e); trace.debug(e, "finalize");
} }
} }
} }
......
...@@ -35,11 +35,25 @@ public class TestCallableStatement extends TestBase { ...@@ -35,11 +35,25 @@ public class TestCallableStatement extends TestBase {
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("callableStatement"); deleteDb("callableStatement");
Connection conn = getConnection("callableStatement"); Connection conn = getConnection("callableStatement");
testCallWithResult(conn);
testPrepare(conn); testPrepare(conn);
conn.close(); conn.close();
deleteDb("callableStatement"); deleteDb("callableStatement");
} }
private void testCallWithResult(Connection conn) throws SQLException {
CallableStatement call;
for (String s : new String[]{"{?= call abs(?)}", " { ? = call abs(?)}", " {? = call abs(?)}"}) {
call = conn.prepareCall(s);
call.setInt(2, -3);
call.registerOutParameter(1, Types.INTEGER);
call.execute();
assertEquals(3, call.getInt(1));
call.executeUpdate();
assertEquals(3, call.getInt(1));
}
}
private void testPrepare(Connection conn) throws SQLException { private void testPrepare(Connection conn) throws SQLException {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
CallableStatement call; CallableStatement call;
......
...@@ -47,9 +47,9 @@ public class TestNativeSQL extends TestBase { ...@@ -47,9 +47,9 @@ public class TestNativeSQL extends TestBase {
"{call TEST('}')}", " call TEST('}') ", "{call TEST('}')}", " call TEST('}') ",
"{?= call TEST('}')}", " call TEST('}') ", "{?= call TEST('}')}", " ?= call TEST('}') ",
"{? = call TEST('}')}", " call TEST('}') ", "{? = call TEST('}')}", " ? = call TEST('}') ",
"{{{{this is a bug}", null, }; "{{{{this is a bug}", null, };
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论