SQLSTATE[HY093]: Número de parámetro no válido: el parámetro no se definió

5 minutos de lectura

k al avatar de usuario de z
k a la z

He estado usando el patrón de registro activo de Yii por un tiempo. Ahora, mi proyecto necesita acceder a una base de datos diferente para una pequeña transacción. Pensé que el DAO de Yii sería bueno para esto. Sin embargo, estoy recibiendo un error críptico.

CDbCommand no pudo ejecutar la instrucción SQL: SQLSTATE[HY093]: Número de parámetro no válido: el parámetro no se definió

Aquí está mi código:

public function actionConfirmation
{
    $model_person = new TempPerson();

    $model = $model_person->find('alias=:alias',array(':alias'=>$_GET['alias']));
    $connection=Yii::app()->db2;
            $sql = "INSERT INTO users (username, password, ssn, surname
                    , firstname, email, city, country) 
                    VALUES(:alias, :password, :ssn, :surname
                    , :firstname, :email, :city, :country)";
            $command=$connection->createCommand($sql);
            $command->bindValue(":username", $model->alias);
            $command->bindValue(":password", substr($model->ssn, -4,4));
            $command->bindValue(":ssn", $model->ssn);
            $command->bindValue(":surname", $model->lastName);
            $command->bindValue(":firstname", $model->firstName);
            $command->bindValue(":email", $model->email);
            $command->bindValue(":city", $model->placeOfBirth);
            $command->bindValue(":country", $model->placeOfBirth);
            $command->execute();
            $this->render('confirmation',array('model'=>$model));
}

Esto construye la siguiente consulta (como se ve en el registro de la aplicación):

INSERT INTO users (username, password, ssn, surname, firstname, email
                   , city, country) 
VALUES(:alias, :password, :ssn, :surname, :firstname, :email, :city, :country);

para su información $model->placeOfBirth se supone que está en valores tanto de ciudad como de condado. Eso no es un error tipográfico (solo una tontería que tengo que hacer).

avatar de usuario de thaddeusmt
tadeo

Solo para proporcionar una respuesta, ya que este error es bastante común, aquí hay algunas causas:

  1. El :parameter el nombre no coincide con el enlace por error (¿error tipográfico?). Esto es lo que pasó aquí. Ellos tienen :alias en la instrucción SQL, pero enlazado :username. Entonces, cuando se intentó el enlace de parámetros, Yii/PDO no pudo encontrar :username en la declaración sql, lo que significa que era “un parámetro corto” y arrojó un error.

  2. Olvidando por completo agregar el bindValue() para un parámetro. Esto es más fácil de hacer en Yii otras construcciones como $criteradonde tiene una matriz o params ($criteria->params = array(':bind1'=>'test', ':bind2'=>'test)).

  3. otra posible razón es un carácter no válido en el nombre del marcador de posición

  4. Conflictos extraños con la paginación y/o clasificación de CDataProvider cuando se usa together y joins. No hay una manera específica y fácil de caracterizar esto, pero cuando uso consultas complejas en CDataProviders, he tenido problemas extraños con la caída de parámetros y este error.

Una forma muy útil de solucionar estos problemas en Yii es habilitar el registro de parámetros en su archivo de configuración. Agrega esto a tu db matriz en su archivo de configuración:

'enableParamLogging'=>true,

Y asegúrese de que CWebLogRoute la ruta está configurada en su log sección. Esto imprimirá la consulta que generó el error y todos los parámetros que intentaba vincular. ¡Súper útil!

  • Buen post. Descubrí en mi instancia que tenía un espacio después de uno de los nombres de las columnas y eso fue suficiente para arrojar el error.

    – salonMonsters

    19 de diciembre de 2011 a las 23:52

  • Una lista de caracteres de marcadores de posición válidos aquí stackoverflow.com/questions/5809951/…

    – chocolata

    8 de julio de 2013 a las 12:04


  • El mío también era un espacio después de uno de los nombres de columna en la llamada de vinculación, hombre que fue difícil de detectar

    –Wesley Smith

    1 de agosto de 2016 a las 12:49


Puede ser que esté tratando de vincular un parámetro entre comillas simples en lugar de dejar que haga el trabajo por usted.

Comparar:

Model::model()->findAll("t.description ilike '%:filter%'", array(':filter' => $filter));

Con:

Model::model()->findAll("t.description ilike :filter", array(':filter' => '%' . $filter . '%'));

Para mí, una causa de este error que no se mencionó anteriormente es cuando se trata de una matriz dinámica de parámetros si desarma algún parámetro, debe volver a indexarlo antes de pasarlo. Mostrar índices para que parezca que todo está bien. P.ej:

SELECT id WHERE x = ?, y = ?, z = ?

Podría generar el registro: número de parámetro no válido: el parámetro no se definió con params (“x”,”y”,”z”)

Parece que no debería arrojar un error, pero si los índices son algo como:

0 => x, 1 => y, 4 => z

Considera el último parámetro indefinido porque está buscando la clave 2.

  • Agregando a su respuesta que un simple print_r mostrará los índices y eso se puede arreglar con array_values ​​ya que reindexará la matriz comenzando en 0

    – chifliiiiiii

    6 sep 2016 a las 17:28

Recibí este error al intentar hacer algo como:

$stmt = $pdo->prepare("select name from mytable where id = :id");
$stmt->execute([
  'id' => $id,
  'unusedvar' => $foo, // This row causes the error.
]);

Básicamente, no puede tener parámetros no utilizados en la matriz pasada a execute(). Cada valor en la matriz pasado a execute() debe usarse en su declaración preparada.

Esto también se especifica en el documentos:

No es posible vincular más valores de los especificados; si existen más claves en input_parameters que en el SQL especificado en PDO::prepare(), la instrucción fallará y se emitirá un error.

¿Ha sido útil esta solución?