0

我正在使用 JDBC PreparedStatement 从 Web 服务中查询 Teradata 数据库。我的表有一个 PHONE_NUMBER 列,存储为 VARCHAR(10)。我一直习惯PreparedStatement setString()为该列提供参数,如下所示:

String myPhoneNumber = "5551234567";    
String sql = "SELECT * FROM MYTABLE " +
             "WHERE PHONE_NUMBER = ? ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);

它返回正确的结果,但我注意到用于此查询的 CPU Teradata 相当高。根据 EXPLAIN 计划,Teradata 似乎将myPhoneNumber参数解释为 FLOAT,而不是 VARCHAR,因此它必须进行数据转换才能将其与 VARCHAR 列进行比较PHONE_NUMBER。以下是 EXPLAIN 计划的摘录:

...
MYDATABASE.MYTABLE.PHONE_NUMBER (FLOAT, FORMAT
'-9.99999999999999E-999'))= 5.55123456700000E 009) 

所以,我想出了以下内容,这表明 CPU 使用率有了很大的提高(提高了 99.86%):

String myPhoneNumber = "5551234567";    
String sql = "SELECT * FROM MYTABLE " +
             "WHERE PHONE_NUMBER = ''||?||'' ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);

所以我的问题是为什么这是必要的?不应该setString告诉 JDBC 告诉 Teradata 期待 String/VARCHAR 参数吗?

谢谢!

4

1 回答 1

0

你有没有尝试过String myPhoneNumber = "'5551234567'";

注意- 包含单引号来包装值。

如果您在此处查看 Teradata 手册中的示例,您将看到设置为与 OP 的第一个示例相同的方式设置的查询带按预期到达,而没有单引号包裹它。在我看来,OP 的第一个示例中的这种行为是预期的。

编辑 Teradata 为其 JDBC 驱动程序提供的示例代码正在使用java.sql.PreparedStatment. 有了这个,他们的示例程序setString无需任何技巧即可为INSERT语句提供字符串值。示例代码如果您无法复制该行为,我将使用 Teradata GSC 打开一个事件。

于 2016-12-01T04:39:52.930 回答