Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

316
Views
PDO::bindValue() falla en la consulta con SELECT anidado

Estoy usando una base de datos MSSQL conectada a través de ODBC.

Cuando se usa PDO::bindValue() en una consulta que tiene una instrucción SELECT anidada, no se pueden vincular valores dentro de la SELECT anidada (no hay problema en la SELECT principal). Esta es una pieza de código de muestra que falla:

 $stmt = $cmdb->prepare("SELECT ci.CI FROM dbo.cmdb_ci AS ci " . "INNER JOIN dbo.cmdb_model AS m ON m.ModelID = ci.Modelid " . "INNER JOIN dbo.cmdb_class AS c ON c.ClassID = m.Classid " . "WHERE (c.ClassID = :classid) " . "AND (ci.CI IN (SELECT ci2.CI " . "FROM dbo.cmdb_ci AS ci2 " . "INNER JOIN dbo.cmdb_ci_status AS st2 ON st2.CI = ci2.CI " . "WHERE st2.LocationID = :locationid))"); $stmt->bindValue("classid", 13); $stmt->bindValue("locationid", 1011); $stmt->execute(); if ($rows = $stmt->fetchAll()) $stmt->closeCursor(); foreach ($rows as $row) echo $row["CI"];

El error que me sale es:

SQLSTATE[22018]: valor de carácter no válido para la especificación de conversión: 206 [Microsoft][SQL Server Native Client 11.0][SQL Server]Conflicto de tipo de operando: el texto es incompatible con int (SQLExecute[206] en /builddir/build/BUILD/php -5.4.16/ext/pdo_odbc/odbc_stmt.c:254)

Si omito el bindValue() para ": locationid" e inserto '1011' directamente en la consulta, la llamada se completa sin errores y con los resultados correctos.

¿Es esto un error en PDO o tengo que llamar a bindValue() de manera diferente?

about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Como (leí de los comentarios) decirle a bindValue que el valor pasado es un número entero no resuelve el problema...

 $stmt->bindValue( "locationid", 1011, PDO::PARAM_INT );

...Supongo que por alguna razón ( ¿un error en pdo_odbc ? ) el parámetro ingresa la consulta como una cadena sin importar lo que especifique como tercer parámetro en bindValue .

Entonces sugeriría solucionar esto convirtiendo el valor en un número entero en su lugar en la consulta.

En la última línea:

 "WHERE st2.LocationID = CAST( :locationid, int ) ))"

Esto no es muy elegante, pero puede ser adecuado hasta que encuentre una solución/parche para pdo_odbc


Si incluso esto no funciona , hay una solución aún menos elegante (que pretende ser una solución temporal, por supuesto).

Tu escribiste:

Si omito el bindValue() para ": locationid" e inserto '1011' directamente en la consulta, la llamada se completa sin errores y con los resultados correctos.

Por lo tanto, puede colocar la identificación de la ubicación directamente en la consulta.

Suponiendo que la identificación de la ubicación se almacena en $locationId , la última línea de la consulta se convierte en:

 "WHERE st2.LocationID = $locationId))");

Como esto es propenso a la inyección de sql, $locationId debe ser desinfectado (o verificado) de antemano.

El valor debe ser un número entero positivo, por lo que en lugar de escapar, sugiero un enfoque más fácil y a prueba de balas: verifique $locationId esté compuesto solo de números...

 if( ! ctype_digit( (string) $locationId ) ) { // location id is invalid // do not proceed ! }
about 4 years ago · Santiago Trujillo Report

0

¿Podría ser que el ID de ubicación esté realmente almacenado en MSSQL como una cadena y no como un int? ¿Funciona cuando agregas comillas? $stmt->bindValue("ubicaciónid", "1011", PDO::PARAM_STR);

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!