2016-11-30 13 views
0

Я использую JDBC PreparedStatement для запроса базы данных Teradata из веб-службы. В моей таблице есть столбец PHONE_NUMBER, который хранится как VARCHAR (10). Я всегда использовал PreparedStatement setString() поставить параметр для этого столбца, как показано ниже:Teradata JDBC не распознает параметр PreparedStatement как VARCHAR без кавычек

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); 

возвращает правильные результаты, но я заметил, что процессор Teradata использует для этого запроса достаточно высок. Согласно плану EXPLAIN, похоже, что Teradata интерпретирует параметр myPhoneNumber как FLOAT, а не VARCHAR, и поэтому он должен сделать преобразование данных, чтобы сравнить его с столбцом VARCHAR PHONE_NUMBER. Вот выдержка из EXPLAIN плана:

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

Итак, я пришел с ниже, которые показали значительное улучшение использования процессора (улучшение 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?

Спасибо!

+1

Это, безусловно, кажется странным. – Kayaman

+0

SetString не добавляет кавычки вокруг ваших параметров. Подумайте об этом с точки зрения concatentation. Если вы concat 'select * from ... where phone_number =' и myPhoneNumber, вы получите 'where phone_number = 5551234567'. Это именно то, что вы просили. Вместо того, чтобы терпеть неудачу, Teradata молча делает (очень дорогой) неявный бросок. – Andrew

+2

@Andrew Не должно * иметь * to. Независимо от формата бинарного файла в Интернете, он должен быть сконструирован в соответствии с установленным типом параметра. Цитаты для удобства чтения, база данных им не нужна. – Kayaman

ответ

0

Вы пробовали String myPhoneNumber = "'5551234567'";

Примечание - Включение в одинарные кавычки, чтобы обернуть значение.

Если вы посмотрите на пример в руководствах Teradata here, вы увидите, что диапазон запросов устанавливается так же, как первый пример OP прибывает, как ожидалось, без одинарных кавычек, обертывающих его. Мне кажется, что такое поведение в первом примере OP ожидается.

РЕДАКТИРОВАТЬ Пример кода обеспечивается Teradata для их драйвера JDBC использует java.sql.PreparedStatment. При этом в их примере программа использует setString без каких-либо трюков для предоставления строкового значения для оператора INSERT. Sample Code Если вы не можете воспроизвести это поведение, я бы открыл инцидент с Teradata GSC.

+1

Это не так, как должны работать параметры, и это выглядит очень несовместимо с стандартами JDBC и SQL. –

+0

Вы правы. Похоже, что драйвер JDBC для Teradata не ведет себя так, как ожидалось. –

+0

Отредактированный ответ на основе комментариев и больше исследований –