Prepared statements, SQLSTATE[HY093]: Invalid parameter number [duplicate] - php

This question already has answers here:
PDO Parameterized Query - Reuse named placeholders?
(5 answers)
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 3 years ago.
I'm trying to write a query to insert/update a table and it's my first time using prepared statements, I'm receiving the error SQLSTATE[HY093]: Invalid parameter number but from what I can see I'm passing all the columns/values required.
(I'm trying to do this without using bindParam as in example #2 here)
This is just a test for now, I plan on making it dynamic once I've actually got a query working.
$data_test = [
':event_id' => 3354,
':event' => 'TESTESTEST',
':staff_booking_id' => 27255,
':is_read' => 'yes',
':priority' => 'medium'
];
$q = "INSERT INTO events(event_id, event, staff_booking_id, is_read, priority)
VALUES(:event_id, :event, :staff_booking_id, :is_read, :priority)
ON DUPLICATE KEY UPDATE event_id = LAST_INSERT_ID(:event_id), event = :event, staff_booking_id = :staff_booking_id, is_read = :is_read, priority = :priority;";
$result = $this->db->prepare($q);
$result = $result->execute($data_test);

As commentented by FunkFortyNiner and tadman, it is possible that the issue comes from the fact that you are reusing the same placeholder.
Actually the MySQL syntax does not require you to reuse the named parameter: you can use the VALUES() to refer to the values initially passed for INSERT.
Also, your attempt to update event_id using LAST_INSERT_ID() does not seem right; I am unsure that this is valid syntax - and anyway, if this is the primary key of table, then you don't want to update it.
Finally, as pinpointed by FunkFortyNiner, event is a reserved word in MySQL, so it needs to be quoted.
$q =
"INSERT INTO events(
event_id,
`event`,
staff_booking_id,
is_read,
priority
)
VALUES(
:event_id,
:event,
:staff_booking_id,
:is_read,
:priority
)
ON DUPLICATE KEY UPDATE
`event` = VALUES(`event`),
staff_booking_id = VALUES(staff_booking_id),
is_read = VALUES(is_read),
priority = VALUES(priority)";

Related

SQL- insert and update in the same method [duplicate]

This question already has answers here:
How to UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) in PostgreSQL?
(7 answers)
Postgres on conflict do update on composite primary keys
(2 answers)
Closed 6 months ago.
I have a problem with my SQL statement written in PHP.
I am using store() function to both INSERT or UPDATE object in the database following it's rule that it can be done:
The INSERT OR UPDATE command is an extension of the INSERT command, with these differences:
If the row being inserted does not exist, INSERT OR UPDATE performs an
INSERT operation. If the row being inserted already exists, INSERT OR
UPDATE performs an UPDATE operation, updating the row with the
specified column values.
I wrote type declaration for the Content ID like : public ?$contentId = null; so I can use the same methods for both actions.
public function store(Content $content, int $teamId)
{
$rsm = new ResultSetMapping($this->entityServiceRepository);
$stmt = $this->entityServiceRepository->getConnection()->prepare(
'UPDATE content
SET
name = :name,
url = :url,
WHERE id = :contentId
AND team_id = :teamId
',
$rsm
);
$stmt->bindValue("contentId", $content->getId(), PDO::PARAM_INT);
$stmt->bindValue("teamId", $content, PDO::PARAM_INT);
$stmt->bindValue("name", $content->getName(), PDO::PARAM_STR);
$stmt->bindValue("url", $content->getUrl(), PDO::PARAM_STR);
$stmt->executeQuery();
However from some reason data does not exist in the database. All bindValue() return true ant other sql queries seems to work well. How can I debug this query? Or can someone tell is there a problem with sql query I wrote.
Thanks.

How to see if mysql replace or insert my query [duplicate]

This question already has answers here:
Find out if REPLACE statement has replaced or just inserted in MySQL
(3 answers)
Closed 4 years ago.
if I have a query with field 1 being a primary key:
$rep = "Replace into table (field1,field2) values ('value1','value2')";
$stmt = $db->query($rep);
Is there a way to tell if mysql inserted the row, or found and replaced the row?
For Posterity:
$rowCount = $stmt->rowCount();
if $rowCount == 1 it was an insert, if $rowCount == 2, it was a replace.
INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE
Timestamp=VALUES(Timestamp)
To achieve this type of task mysql provide us DUPLICATE KEY UPDATE.
Below is the example how you will create new record if record is not exists in database otherwise it will update record
$rep = "INSERT into table (primaryField,field2) values ('value1','value2') ON DUPLICATE KEY UPDATE primaryField=VALUES(primaryField)";
$stmt = $db->query($rep);
For more detail you can read this
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html
I think this will help you.

use insert and select in the same query [duplicate]

This question already has an answer here:
MYSQL INSERT SELECT problem
(1 answer)
Closed 6 years ago.
$new_id = mysqli_insert_id($dbc)
foreach ($_POST['d_specialty'] as $key => $value) {
$q = "INSERT INTO d_specialty (d_id, s_id) VALUES ($new_id, (SELECT specialty.id FROM specialty WHERE specialty.name = $value))";
$r = mysqli_query($dbc,$q);
i want to insert two values, the first one is a variable and the second is a select statement but the code above does not work...
First, use insert . . . select:
INSERT INTO d_specialty (d_id, s_id)
SELECT $new_id, specialty.id
FROM specialty
WHERE specialty.name = $value;
Second, parameterize the query so $new_id and $value are passed in as parameters rather than put directly into the query string. One reason is to prevent SQL injection attacks. Another very important reason is to guard against potential syntax errors.
When using insert into select you don't need to use values. Remove that and then move the $new_id variable into the select statement:
INSERT INTO d_specialty (d_id, s_id)
SELECT $new_id, specialty.id
FROM specialty
WHERE specialty.name = $value

PDO query with php variables [duplicate]

This question already has answers here:
Can PHP PDO Statements accept the table or column name as parameter?
(8 answers)
Closed 8 years ago.
Why this line doesn't work:
$db_Table = "myTable";
$pdo->prepare("INSERT INTO :db_Table VALUES (...
$query->execute(array(
':db_Table' => $db_Table,
Whereas this one works:
$pdo->prepare("INSERT INTO myTable VALUES (...
How can I solve it ?
Tablenames can not be replaced in a PDO Query.
Further information you can find in the following thread
Can PHP PDO Statements accept the table or column name as parameter?
unfortunately there are no builtin function for binding table names, you have to do it yourself:
$db_Table = "myTable";
$query = $pdo->prepare("INSERT INTO `$db_Table` VALUES (...)");
$query->execute();
But that is still not being escaped, one workaround is to have an array of table, then check if it exist:
$list_of_tables = array('myTable1', 'myTable2', 'myTable3');
if(!in_array($db_Table, $list_of_tables){
//table does not exist !
}

Possibilites #mysql_affected_rows return Values? [duplicate]

This question already has answers here:
Possible return values for mysql_affected_rows()
(2 answers)
Closed 9 years ago.
Can anyone please tell me what are all the possibilities of return values for #mysql_affected_rows. Because i am checking if(#mysql_affected_rows()). In most case it returns 1(sucess) or 0(not sucess). So it worked correctly. But in some cases it returns some value other than 0 if not success on updation.
I dont know what it returns. But it come into the loop. Inside loop i am trying to insert the data. But it shows duplication error on SQL for that. For your reference check the below code please,
$sqlU = sprintf("UPDATE %s SET count = count + 1
WHERE id = %d", 'table', 123);
mysql_query($sqlU);
if(!#mysql_affected_rows()) {
$sqlI = sprintf("INSERT INTO %s (id) VALUES (%d)",
'table', 123);
mysql_query($sqlI);
}
First, the mysql_* functions are deprecated. mysql_affected_rows() seems to return an integer in all cases. It returns -1 if the query failed.
What you really need instead of mysql_affected_rows() is a proper query that is not open to race conditions.
INSERT INTO table (id, count) VALUES (123, 0) ON DUPLICATE KEY UPDATE count = count + 1

Categories