Use a function call in PDO's bindValue() - pdo

This doesn't work:
public function persist( Forwarding $Forwarding ) {
$sql = "INSERT INTO forwarding ( inbound_id ) VALUES ( :inbound_id )";
$statement = $this->pdo->prepare( $sql );
$statement->bindValue(':inbound_id', $Forwarding->getInboundId() );
$query = $statement->execute();
}
because the bound value is always NULL. Is it not possible to use callbacks to bind values for PDO's prepare statement?

Related

How can I add to an existing value in sql table

How can i add a value to an existing value in SQL example a value 4 in a column how can i add 2 to it to make it 6 not to update to 2 but to add the previous value and the new value to together here is my class php file
<?php
class data
{
public $d_count;
public $id;
private $conn;
private $table_name;
public function __construct($db)
{
$this->conn = $db;
$this->table_name= "tbl_data";
}
public function updateCount()
{
// $query = "UPDATE tbl_data SET d_count = ?, date_updated = ? WHERE id = ?";
$query = "UPDATE tbl_data SET d_count '+1' = ?, date_updated = ? WHERE id = ?";
$obj = $this->conn->prepare($query);
$this->d_count = htmlspecialchars(strip_tags($this->d_count));
$this->date_updated = htmlspecialchars(strip_tags($this->date_updated));
$this->id = htmlspecialchars(strip_tags($this->id));
$obj->bind_param("sss", $this->d_count, $this->date_updated, $this->id);
if ($obj->execute()) {
return true;
}
return false;
}
}
The line I commented out is what i used to test the code and it works fine but now i need to add the old value + new value together here is the code am using to update the table
<?php
$data = new data($connection);
if($_SERVER['REQUEST_METHOD'] === "POST"){
$newDCount = json_decode(file_get_contents("php://input"));
if(!empty($newDCount->d_count))
$data->id= $newDCount->id;
$data->d_count = $newDCount->d_count;
$data->date_updated = date('Y-m-d H:i:s', time());
if($apiata->updateCount()){
http_response_code(200);
echo json_encode(array(
"status" => 200,
"message" => "Success"
));
}
else
{
http_response_code(200);
echo json_encode(array(
"status" => 500,
"message" => "Failed"
));
}
}
To update the d_count to add to the existing d_count value, the query should look like:
$sql = 'UPDATE catalog SET d_count = d_count + ?, date_updated = ? WHERE id = ?';
The other handling should be ok as-is.

Query through PreparedStatement in H2 throws exception: This method is not allowed for a prepared statement; use a regular statement instead

A simple query fails when run through a prepared statement while using JDBC 4 to access an H2 database in Java 11.
When running this line:
try ( ResultSet rs = pstmt.executeQuery( sql ) ; ) {
…I get this error:
org.h2.jdbc.JdbcSQLException: This method is not allowed for a prepared statement; use a regular statement instead. [90130-197]
I tried using the H2 Error Analyzer, but no help there.
Here is a complete example app, in a single .java file. You can copy-paste and run yourself.
package com.basilbourque.example.work.basil.example.h2.pstmt_query;
import org.h2.jdbcx.JdbcDataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class App {
public static void main ( String[] args ) {
App app = new App();
app.doIt();
}
private void doIt ( ) {
// Create database.
try {
Class.forName( "org.h2.Driver" );
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
}
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL( "jdbc:h2:mem:pstmt_query_example_db;DB_CLOSE_DELAY=-1" ); // Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
dataSource.setUser( "scott" );
dataSource.setPassword( "tiger" );
// Create table.
try (
Connection conn = dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
) {
String sql = "CREATE TABLE person_ ( \n" +
" pkey_ UUID NOT NULL DEFAULT RANDOM_UUID() PRIMARY KEY , \n" +
" name_ VARCHAR NOT NULL \n" +
");";
System.out.println( sql );
stmt.execute( sql );
} catch ( SQLException e ) {
e.printStackTrace();
}
// Query table.
List < UUID > list = new ArrayList <>();
String sql = "SELECT * FROM person_ WHERE name_ = ? ;";
try (
Connection conn = dataSource.getConnection() ;
PreparedStatement pstmt = conn.prepareStatement( sql ) ;
) {
String name = "Wendy Melvoin";
pstmt.setString( 1 , name );
try ( ResultSet rs = pstmt.executeQuery( sql ) ; ) { // org.h2.jdbc.JdbcSQLException: This method is not allowed for a prepared statement; use a regular statement instead. [90130-197]
while ( rs.next() ) {
UUID pkey = rs.getObject( "pkey_" , UUID.class );
list.add( pkey );
}
}
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}
Exception reported:
org.h2.jdbc.JdbcSQLException: This method is not allowed for a prepared statement; use a regular statement instead. [90130-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.get(DbException.java:144)
at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:302)
at com.basilbourque.example.work.basil.example.h2.pstmt_query.App.doIt(App.java:53)
at com.basilbourque.example.work.basil.example.h2.pstmt_query.App.main(App.java:13)
Passing the SQL string twice
On a PreparedStatement, you never pass the SQL string to executeQuery method. You do so in an unprepared Statement, but not PreparedStatement. Notice how the JavaDoc for PreparedStatement::executeQuery takes no argument.
So your line:
try ( ResultSet rs = pstmt.executeQuery( sql ) ; ) {
…should be:
try ( ResultSet rs = pstmt.executeQuery() ; ) {
You already passed the SQL string named sql above that line, when you prepared the statement:
PreparedStatement pstmt = conn.prepareStatement( sql ) ;
Since the PreparedStatement named pstmt already holds your SQL statement(s), there is no need to pass into executeQuery.
This mistake might have been the result of copy-pasting some code using Statement for reuse in some other code using PreparedStatement.

How to make a query based on a view?

The standard way to make a query against a database table is to create a model and create a function within it , for example :
<?php
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Query;
class Client extends Model {
function lireParCritere($critere) {
$sSQL = "
SELECT c.clt_id as clt_id,c.clt_cin_pass,c.clt_nom,c.clt_prenom,c.clt_tel,
c.clt_adresse,c.clt_comment,CONCAT_WS(
' ',
c.clt_nom,
c.clt_prenom
) AS noms
FROM Client as c WHERE 1 = 1 ";
if(isset($critere["clt_id"]) && $critere["clt_id"] != "") {
$sSQL .= "AND c.clt_id = '" . $critere["clt_id"] . "' ";
}
$sSQL .= " ORDER BY noms";
$query = new Query($sSQL,$this->getDI());
$ret = $query->execute();
return $ret;
}
}
?>
What is the way to make a query against a database view ?
A database view is basically the output of a SQL query stored in another table. You can think of a view as an alias for a specific SQL query that you can then run other queries on top of. (kind of like SELECT * FROM (SELECT * FROM table_one, table_two, table_n);)
This means that you can treat the view as a regular table and pull from it without any issues.
So lets say you have a database view that has three columns id, col_one, col_two. You could do something similar to the following.
<?php
/**
* Model representing the database view
*/
class Example extends \Phalcon\Mvc\Model
{
public $id;
public $col_one;
public $col_two;
public function getSource()
{
return 'view_name_in_database';
}
public function columnMap()
{
return array(
'id' => 'id',
'col_one' => 'col_one',
'col_two' => 'col_two'
);
}
}
// example query on the model
$examples = Example::query()
->where('id = :id:')
->bind(array(
'id' => 55
))->execute();
?>

Zend/db/Sql/ query syntax

I am starting with Zend Framework 2 , I want to make a routing choice with the role of My user and I must write getRoleByID($id) ,
then
How can'I write
" Select 'role' from user where ('id' = $id) " with Zend\Db\Sql
Example Using Select:
$select = new \Zend\Db\Sql\Select('user');
$select->columns(array('role'));
$where = new Where();
$where->equalTo('id', $id);
$select->where($where);
/**
* Simple example of executing a query...
*/
$stmt = $this->getSql()->prepareStatementForSqlObject($select);
$results = $stmt->execute();
/* #var $results \Zend\Db\Adapter\Driver\Pdo\Result */
if( ! $results->count()) {
// do something, none found...
}
$row = $results->current();
return $row['role'];
// if you had multiple results to iterate over:
//$resultSet = new \Zend\Db\ResultSet\ResultSet();
//$resultSet->initialize($results);
//$array = $resultSet->toArray();
//foreach($resultSet as $row) { /* ... */ }

ZF2 insert multiple rows

I'd like to know if there is a way to insert multiple row in ZF2 using only one $sql object (and not using the query(SQL COMMAND) method).
I tried something like this, but it doesn't work:
public function setAgentProjectLink( $IDProject , $IDsAgents )
{
$values = array () ;
foreach ( $IDsAgents as $IDAgent):
{
$values[] = array ( 'id_agent' => $IDAgent , 'id_projet' => $IDProject) ;
} endforeach ;
$sql = new Sql( $this->tableGateway->adapter ) ;
$insert = $sql->insert() ;
$insert -> into ( $this->tableGateway->getTable() )
-> values ( $values ) ;
$statement = $sql->prepareStatementForSqlObject($insert);
$result = $statement->execute();
}
Trying to insert values in a database with two columns (id_agent, id_projet)
there is no generic way for multyinsert in ZF2 BUT if you are using mysql and not planning to change to other databases, i have written a multiInsert function for myself:
$data is an array of arrays of key,value pairs.
protected function multiInsert($table, array $data)
{
if (count($data)) {
$columns = (array)current($data);
$columns = array_keys($columns);
$columnsCount = count($columns);
$platform = $this->db->platform;
array_filter($columns, function ($index, &$item) use ($platform) {
$item = $platform->quoteIdentifier($item);
});
$columns = "(" . implode(',', $columns) . ")";
$placeholder = array_fill(0, $columnsCount, '?');
$placeholder = "(" . implode(',', $placeholder) . ")";
$placeholder = implode(',', array_fill(0, count($data), $placeholder));
$values = array();
foreach ($data as $row) {
foreach ($row as $key => $value) {
$values[] = $value;
}
}
$table = $this->db->platform->quoteIdentifier($table);
$q = "INSERT INTO $table $columns VALUES $placeholder";
$this->db->query($q)->execute($values);
}
}