pdo - prepared statement loses data? - php

I have a query (PHP, Mysql) a table named 'table' that looks like this:
id | name
-------------
6 | abc
10| xxx
52| def
And a query:
$ids = '5,62'
$name = $pdo -> prepare('SELECT id, name FROM table WHERE id IN ( :ids )');
$name -> bindValue(':ids', $ids, PDO::PARAM_STR);
$name -> execute();
$name = $name->fetchAll(PDO::FETCH_ASSOC);
print_r($nazwa);
I would expect to get a result like
id | name
-------------
6 | abc
52| def
Unofrtunately i get only:
id | name
-------------
6 | abc
As if second value would be ignored. If I change the query to:
$name = $pdo -> prepare('SELECT id, name FROM table WHERE id IN (' $ids ')');
It all goes right. Can you tell me why prepared statement doesnt take under consideration imploded table with commas?

Because the comment field does not allow to write that well, here an answer that is merely a comment:
Let's say you have two IDs:
$name = $pdo->prepare('SELECT id, name FROM table WHERE id IN ( :id1, :id2 )');
Let's say you have three IDs:
$name = $pdo->prepare('SELECT id, name FROM table WHERE id IN ( :id1, :id2, :id3 )');
You see the pattern? You have as many values as you have IDs. Formulate the prepare statement as well as perform the bind statements accordingly to the number of IDs you have.
So the answer is: You need to change your code so that it actually reflects the number of IDs you want to handle. The MySQL server will not magically interpret a comma-separated list inside a string as multiple IDs. Instead you need to tell the server about each single ID.

Related

Send array from js to php to SQL database

I hope I'm missing something easy here.
I have an array created in js, say: var ids = [1,2,3,4,5];
Now I want this array to populate a column in my SQL database table.
I have the pipeline setup for adding single elements to my table like this:
request is sent via ajax:
$.ajax({
type: "POST",
url: "some.php",
data: {
ids: ids,
}
});
some.php receives the data (connection, etc. is set up):
$ids = $_POST['ids'];
SQL is used to insert single values to the column COL_ID
$sql = "INSERT INTO `mydb`.`dbtable`(`COL_ID`) VALUES ('$ids)";
This pipeline works for single values (e.g. of ids = 2 but fails for an array.
What I'd want is for COL_ID to contain each array element as a row
| COL_ID |
|-------- |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
I suspect it's in the SQL query. Any help is welcome.
First, use prepared statements, don't insert post data directly into a database query. Using post data directly means you are vulnerable to sql injection attacks.
As #DanielReed indicated, the correct format is
INSERT INTO table_name (column_list) VALUES (value_list_1), (value_list_2), (value_list_3);
You can build this dynamically:
$ids = $_POST['ids'];
// Make sure we get the correct number of ? for prepared statements
$params = str_repeat('(?), ', count($ids));
// Strip the trailing space and comma
$params = substr($params, 0, -2);
$sql = 'INSERT INTO `mydb`.`dbtable`(`COL_ID`) VALUES ' . $params;
Now you can use $sql as your query and $ids as the values for the prepared statement. This prevents sql injection.
PHP receives it as an array.
SQL Syntax wants it in the following syntax:
INSERT INTO table_name (column_list)
VALUES
(value_list_1),
(value_list_2),
...
(value_list_n);
So what you could do is:
$sql = "INSERT INTO `mydb`.`dbtable`(`COL_ID`) ";
foreach($ids as $value){
$sql .= "(".$value.") ";
}

mysql select and insert safely and quickly with php

I have a simple table, the logic is that before inserting a new row, I should fetch one column from that table. Let me explain:
table
id key groupId Note
1 00001 1 abd
2 00002 1 aasdas
3 00003 1 aasdas
4 00001 2 q2eqwd
5 00002 2 qwdvvd
6 00003 2 qwrqw
7 00004 2 qwdqdqw
You see, key increases like Auto Increment for each groupId.
When group with id 2, wants to add a new note, he should know last key. After finding it, php addes +1 to last key and inserts a new row. I do it like below:
$groupId = 2; //for example
$note = $_POST['note'];
$select = $db -> prepare("SELECT key FROM table where groupId = :groupId ORDER BY id DESC limit 1");
$select -> bindValue(":groupId", $groupId, PDO::PARAM_INT);
$select -> execute();
$fetch = $select -> fetch(PDO::FETCH_ASSOC);
$lastKey = $fetch['key']+1;
$insert = "INSERT INTO table (key, groupId, note) VALUES(:key, :groupId, :note)";
$ins = $db -> prepare($insert);
$insert -> bindValue(":key", $lastKey, PDO::PARAM_INT);
$insert -> bindValue(":groupId", $groupId, PDO::PARAM_INT);
$insert -> bindValue(":note", $note, PDO::PARAM_STR);
This method works good for me, but I am afraid of is here will be any conflict while fetching last key from table? Because, at the same time, 10 user with same groupId can add a new row. May php fetch same key to 3 users with group ID 2 at the same time?
Is there any quickly and safely way?
You can do this with AUTO_INCREMENT using MyISAM.
From MySQL Docs:
For MyISAM and BDB tables you can specify AUTO_INCREMENT on a
secondary column in a multiple-column index. ... This is useful when you want to put data into ordered groups.
Otherwise, you should set the value in your insert query with a subquery like SELECT MAX(key) + 1 FROM table WHERE groupID = 1 and read back the value.

SQL - Inserting data where values are an array

I want to be able to add an array of strings to a table so that each string is a new row (in PHP).
This is it in psuedo-code:
$Array = "10000,10001,10002,10003";
$Data = "ImportantData";
mysqli_query($db, "INSERT INTO MyTable(`id`,`data`) VALUES($Array, $Data)");
So that a previously empty table would look like:
id | data
------------------------
10000 | ImportantData
10001 | ImportantData
10002 | ImportantData
10003 | ImportantData
In an update script, with those rows already established, I could just say:
mysqli_query($db, "UPDATE MyTable SET data = $Data WHERE `id` IN($Array));
However I want it to create rows, not just update old ones.
Is there any way I can do this?
Just create a foreach loop on $Array, and insert the data. I assume you want to update it if it exists as it makes little sense to create a new record with the same PK, so use the following (assumes you are using PHP PDO
INSERT INTO MyTable (id,data) VALUES (:id,:data) ON DUPLICATE KEY UPDATE data=:data;
Use REPLACE INTO:
REPLACE INTO table SET id = 10001, data = 'new important data';
MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/replace.html

Insert multiple columns into table using mysqli

I'm trying to insert form data into my sql table. The form data is a long questionnaire that has multiple questions. This means that the table I'm inserting into has multiple columns, 30 to be exact.
Is there a way for me to quickly insert one row of 30 columns with minimal or efficient code? Perhaps I can have the "name" value in my form be equal to the variable name in the my table? My form is a mixture of normal text fields and some checkbox groups.
I'm using php and hoping to use mysqli prepared statements.
TLDR: Can I shorten this ?:
$query = "INSERT INTO table (a, b, c, d, e , f , g , h ,i j, ........)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,....)";
mysqli_stmt_bind_param($stmt,'sssiiisiiiiiiiiiisss...', ....);
Or do I need to just brute force it?
You could try to call mysqli_stmt_bind_param using call_user_func_array and pass in an array of parameters:
$sql_link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
$type = "isssi";
$param = array("5", "File Description", "File Title", "Original Name", time());
$sql = "INSERT INTO file_detail (file_id, file_description, file_title, file_original_name, file_upload_date) VALUES (?, ?, ?, ?, ?)";
$sql_stmt = mysqli_prepare ($sql_link, $sql);
call_user_func_array('mysqli_stmt_bind_param', array_merge (array($sql_stmt, $type), $param);
mysqli_stmt_execute($sql_stmt);
source
Afaik no you can't shorten it.
But you could change your DB model that a result record only contains one answer which is linked to the question and to the user the answer is from. So you are also variable on how many questions there are in a quiz. And you don't have an oversize of 28 columns if the quiz only have 2 questions.
table: user
-----------
id (PK)
username
table: quiz
-----------
id (PK)
title (FK)
table: question
---------------
id (PK)
question
quiz_idfk (FK)
table: answer
-------------
id (PK)
answer
question_id (FK)
user_id (FK)
With that model the insert of a result would be (only pseudo code):
foreach($_POST['answer'] as $qid => $ans) {
// sql: INSERT INTO answer SET answer = :ans, question_id = :qid, user_id = :uid
// :ans the answer text ($ans)
// :qid the question id ($qid)
// :uid the currently logged in user
}

Need MYSQL query to insert value in different columns?

I am using Php to insert values into MySQL table.
What i am trying to do is:
There are three columns that i have to check. 'namel1', 'namel2' and 'namel3'.
Conditions:
If '$name' does't exist in any of the three column then put value in 'namel1'.
If '$name' exist in 'namel1' then put value in 'namel2' and if 'namel2' contains the value then put it in 'namel3'.
My current MySQL query to insert name and image path is this i want to modify it to meet above conditions:
$chk_img_db = mysql_query("select * from cvapptable where img_path='$cvh_myimg_url'");
if(mysql_num_rows($chk_img_db)<1) {
mysql_query("insert into cvapptable(namel1,img_path) values ('$name','$cvh_myimg_url')");
}
I unable to get any solution from web.
Please help. Thank you.
It's not easy to find on the net because it's a situation you shouldn't get yourself into.
You should consider normalizing the table.
Instead of having a table with the columns:
cvapp: id | img_path | namel1 | namel2 | namel3
Consider changing it to two tables:
cvapp: id | img_path
names: id | cvapp_id | name
To then select every name, you just do a query like so:
SELECT name
FROM cvapp INNER JOIN names on cvapp.id = names.cvapp_id
WHERE <condition>
That way, you can have as many names as you want, and it's much easier to insert a new one:
INSERT INTO names (cvapp_id, name) VALUES (56, "Name 1");
INSERT INTO names (cvapp_id, name) VALUES (56, "Name 2");
INSERT INTO names (cvapp_id, name) VALUES (56, "Name 3");
you can try self join and search column of you tables

Categories