2015-11-27 1 views
2

У меня возникла странная ошибка с подготовленными заявлениями с помощью DataStax php driver 1.0.0-rc и Cassandra 2.2.3. Я получил исключение на этой линии:Cassandra Подготовленные сообщения об ошибке с драйвером datastax php

$statement = $this->session->prepare("SELECT ? FROM ? WHERE ? = ?"); 

Я вижу эту ошибку:

"error_code":33562624 
"error_message":"Bind variables cannot be used for keyspace names" 

Ниже заглушка класса, используемой общаются с Кассандрой:

class ClsCassandra extends ClsDbObject 
{ 
    private $hostname=""; 
    private $username=""; 
    private $password=""; 
    private $keyspace=""; 
    private $poi_table=""; 
    private $poi_table_key_field=""; 
    private $poi_table_content_field=""; 

    private $cluster = NULL; 
    private $session = NULL; 

    private $threads = 1; 

    function __construct() 
    { 
     ... 
     ... 
     // 
     // i set up all the properties above 
     // 
     ... 
     ... 
    } 

    public function runQuery(&$error) 
    { 
     try 
     {   
      $this->cluster = Cassandra::cluster() 
      ->withContactPoints($this->hostname) 
      ->withCredentials($this->username, $this->password) 
      ->withIOThreads($this->threads) 
      ->build(); 

      $this->session = $this->cluster->connect($this->keyspace); 

      // error on next line... 
      $statement = $this->session->prepare("SELECT ? FROM ? WHERE ? = ?"); 
      $results = $this->session->execute($statement, new Cassandra\ExecutionOptions(array(
        'arguments' => array($this->poi_table_content_field, $this->poi_table, $this->poi_table_key_field, $keypattern) 
      ))); 

     } 
     catch(Cassandra\Exception $ce) 
     { 
      $error->setError($ce->getCode(), $ce->getMessage(), $ce->getTraceAsString()); 
      $this->log(LOG_LEVEL, $error->getErrorMessage(), __FILE__, __LINE__, __CLASS__); 
      return false; 
     } 
     return true; 
    } 

    ... 
    ... 
    ... 
} 

Если я использую Simple Statemetn со стандартным запросом выбора, а не работает.

Любые предложения?

ответ

1

Вы видите эту ошибку, потому что вы можете связывать переменные только с предложением WHERE. Подготовленный механизм высказывания - это не просто прославленный струнный форматтер. У этого есть правила о том, что может и не может быть связано, и как вы должны связывать вещи, чтобы удалить любую двусмысленность при отправке в Кассандру.

Вам нужно попробовать что-то вроде этого:

$statement = $this->session->prepare(
    "SELECT key1, key2, col1, col2 FROM yourKeyspaceName.yourTableName WHERE key1 = ? AND key2 = ?"); 
$results = $this->session->execute($statement, new Cassandra\ExecutionOptions(array(
    'arguments' => array($key1,$key2) 
    ))); 
+0

Дорогой Аарон, большое спасибо за вашу помощь. Следуя вашим намекам, я решил. есть ли сайт, на котором я могу увидеть подробное правило, которое будет применяться для подготовленного заявления? Thx заранее. – omambe

+0

@omambe Вот ссылка на документацию драйвера Java (http://docs.datastax.com/en/developer/java-driver/2.0/java-driver/quick_start/qsSimpleClientBoundStatements_t.html), которая гласит: «использовать подготовленные заявления и привязывать новые значения к столбцам каждый раз перед исполнением ». Идея подготовленного заявления состоит в том, что вы строите CQL раньше времени и отправляете разные значения столбцов с каждым запросом (для производительности). Как Cassandra может сохранить запрос для будущего использования, если вы каждый раз будете менять имя столбца, таблицы или ключа? – Aaron

+0

@omambe Вы также можете найти эти два сообщения в блоге: http://www.datastax.com/dev/blog/4-simple-rules-when-using-the-datastax-drivers-for-cassandra и https://ahappyknockoutmouse.wordpress.com/2014/11/12/246/ – Aaron