I don't know how to make one of my columns (ListOfAvailableSeats) an array.I've tried but nothing works.Can you give me a hint, please? This is the latest version of the code:
ALTER TABLE `newconnectionmviescinema`.`allmovies`
CHANGE COLUMN `LastUpdate` `LastUpdate` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER `Duration`,
CHANGE COLUMN `` `ListOfAvailableSeats` INT(60) NOT NULL ;
INSERT INTO `allmovies`.`ListOfAvailableSeats` VALUES ('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15');
Since MySql doesn't have an array type for storage, why not encode the array as JSON, and store the resulting string? Then decode it when you need to use the array from the table.
If I was doing this in php, I'd use something along the lines of:
<?php
$values = array();
array_push($values, 1);
array_push($values, 2);
array_push($values, 3);
array_push($values, "chicken");
$toStore = json_encode($values);
//Store $toStore as you would any other large string.
//When you need it use it like this:
$freeSeats = "";
$data = json_decode($jsonFromDatabase); //If you had an associative array like $data['name'], then you would add json_decode($jsonFromDatabase, true);
foreach($data as $seat){
$freeSeats .= $seat . ", ";
}
echo "The free seats are " . $freeSeats;
?>
Related
I'm getting a strange result, where an update method (http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#update) call that activates/deactivates site users accounts in my mySQL database sometimes are not updated and returns a 0. Here is the code:
$user_id = '198';
$sqlSetStmnt= [ 'activation_code' => NULL, 'active' => 0 ];
$conn = $this->get( 'database_connection' );
try {
$result = $conn->update( 'users', $sqlSetStmnt,[ 'id' => (int)$user_id ] );
}
catch( Exception $e ) {
$error = $e->getMessage();
throw new \Exception( 'update user account data function -- ' .
'error: ' . $error . ' - ' .
'unable to update your account!' );
} // End of catch( Exception ) block.
if( ( $result === FALSE ) || ( $result !== 1 ) ) {
throw new \Exception( 'update user account data function -- ' .
'update return value: ' . $result . ' - ' .
'unable to update your account!' );
} // if( ( $result === FALSE ) || ( $result !== 1 ) ) ...
The users table has an id int(11) column which is the primary key, an active tinyint(1) column, and activation_code varchar(40) NULL column.
Please note the $user_id variable contains a string value of '198', but it is cast to an int when creating the $sqlSetStmnt value.
Inspecting the users table confirms that there was a row in the users table with the id column value of 198 at the time of the update call.
The account used when running the update call has enough privileges to change the row active and activation_code column values.
There are no other users in the system or accessing the database, so there aren't any locks on the row.
I inspected the code using x-debug, and the values of the $user_id and $sqlSetStmnt variables were properly set to the values that I expected, that $result was set to 0 by the update method, and that no exceptions were thrown by the update method call.
By the way, there is no need to using variable binding because the values in the $user_id and $sqlSetStmnt variables are not input by an user, so no possibility of SQL-Injection, or Buffer-Overrun.
Is there some way to get information from DBAL about why the update method returned 0?
Thank you.
Before solving this issue I switched from:
$result = $conn->update( 'users', $sqlSetStmnt, [ 'id' => (int)$user_id ] );
to:
$sqlUpdateStmnt = 'UPDATE `users` SET field = value ' .
'WHERE `id` = ' . $user_id;
$result = $conn->executeUpdate( $sqlUpdateStmnt );
and got exactly the same result, where some updates would return 0 rows when there definitely was a row in the users table with an id matching the value of $user_id.
I got around this problem by fetching the existing row and then only updating the row when the fields in the set-clause were different than the same columns from the table.
This tells me that the 0 return value wasn't that there were no matching rows, but that the updated didn't have any effect on any rows.
So this issue isn't a bug, so much as a misunderstanding of the result. However, the problem still exists when using the update() method of how to determine when the update failed due to no matching rows and when no changes were made.
The solution that I ended up solves this at the cost of a pre-fetch to verify that the update would affect a row. In my case, with a multi-user database application, pre-fetching isn't actually a problem because the row that is to be updated could have been deleted by another user before the update tries to make its change. But, it would be nice if both update methods explained this more clearly, and returned different values: 0 for no affected rows and FALSE for no rows found.
I have a table structure with META_ID | KEY | VALUE | USER_ID where META_ID is auto-increment. Now in my php logic
1 get the result key-value pairs per user
2 delete the key value row per user
3 update or insert the key value pair for a already known USER_ID
4 insert key value pair for a new user
But the META_ID keeps growing, so i was wondering if i could just delete the META_ID column?
Case logic
An registered user or returning registered user can update their form over time if they haven't submit it yet. So overtime an user can select and deselect certain form options and update, insert or delete is triggered.
Now the logic behind "returning user deselects a key (and the row needs to be deleted)" gives me a problem. That's why i just delete all users key-value pairs. But what would be the right way?
So if the key-value exists in the db table but not in $params i need to delete it!
btw here's my function
function user_shopping_meta_data($params) {
global $wpdb;
$shopping_meta_table = 'wp_shopping_metavalues';
$wp_user_id = $params['wp_user_id'];
//1 CHECK IF USER HAS KEY VALUE PAIRS
$checkKeyValues = $wpdb->get_results("SELECT meta_shopping_key FROM $shopping_meta_table WHERE wp_user_id = '$wp_user_id'");
//2 WE DELETE
$qdel = $wpdb->delete($shopping_meta_table, array('wp_user_id' => $wp_user_id));
//3 UPDATE OR INSERT
foreach ($params as $key => $val) {
//variables
if (is_array($val)) {
$val = json_encode($val);
}
$shopping_meta_values = array(
'wp_user_id' => $wp_user_id,
'meta_shopping_key' => $key,
'meta_shopping_value' => $val
);
if (count($checkKeyValues) > 0) {//3 USER IS KNOWN SO UPDATE and/or INSERT new key-value
foreach ($checkKeyValues as $check) {
//UPDATE OR INSERT
if (($key != "wp_user_id")) {
//FOR UPDATE where
$shopping_meta_where = array('meta_shopping_key' => $key, 'wp_user_id' => $wp_user_id);
$result = $wpdb->get_results("SELECT * FROM $shopping_meta_table WHERE meta_shopping_key = '" . $key . "' AND wp_user_id = '$wp_user_id'");
if (count($result) > 0) {//KEY ALREADY EXISTS FOR USER
$return .= $wpdb->update($shopping_meta_table, array('meta_shopping_key' => $key, 'meta_shopping_value' => $val), $shopping_meta_where) . '<br/>';
//$return .= 'UDPATE<br/>';
} else {//KEY IS NEW
$return .= $wpdb->insert($shopping_meta_table, $shopping_meta_values) . '<br/>';
// $return .= 'INSERT for old';
}
}//.end $key
}//.end foreach checkKeyValue
}//.end count
else {//4 INSERT KEY VALUE PAIR FOR NEW USER
if (($key != "wp_user_id")) {
$return .= $wpdb->insert($shopping_meta_table, $shopping_meta_values) . '<br/>';
// $return .= 'INSERT NEW';
}
}
}//.end each
echo 'Test return: ' . $return;
}
You won't gain much by deleting it. You might think that you save some space, but in fact you don't. An auto_increment column is always also (part of) the primary key. If you delete it, MySQL will create an "implicit" primary key, which is not visible but necessary for MySQL to identify rows. Also you will lose some comfort like not being able to use LAST_INSERT_ID().
You can very well delete it. It is just a unique ID. If you can distinguish different rows without the META_ID or you do not need to distinguish rows, then META_ID is redundant.
If i can give you a suggest is better to leave that field as a history.
If you need to want to know what is the last action done for that user you can order by META_ID.
Is usefull to have a primary key in a table. But this is just a suggest
I suggest you have a primary key that you are sure of that it is unique. It is a good idea to use a auto-increment column for this because you will always be sure that it is unique.
I have this context:
CREATE TABLE `atdees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`params` text NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `atdees` (`id`, `params`) VALUES
(1,'{"field282":"0","field347":"1"}'),
(2,'{"field282":"0","field347":"0"}'),
(3,'{"field282":"0"}');
I have to extract from the table the rows where :
an atdee must have the string '"field282":"0"'
an atdee has the string '"field282":"0"' but not the string '"field347":"0"'
an atdee has both string '"field282":"0"' and '"field347":"0"'
In other words I have to extract the Id 2 and 3.
Thank you.
Ps: Sorry for my english, I am not a native speaker ;)
edit: well i found my query
SELECT id
FROM atdees
WHERE
INSTR(`params`, '"field282":"0"') > 0 and
( params LIKE '%"field347":"0"%' OR
INSTR(`params`, '"field347"') = 0 )
If it's simply getting data from the database, then you can use something like this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('id'));
$query->from($db->quoteName('#__atdees'));
$query->where($db->quoteName('params') . " = " . $db->quote('"field282":"0"') . "OR" . $db->quote('"field347":"0"'));
$db->setQuery($query);
$results = $db->loadObjectList();
foreach ( $results as $result ) {
echo "<p>" . $result->id . "</p>";
}
Not sure if the database table is for a Joomla extensions but if so, keep it as #__atdees in your query, else change to atdees
Hope this helps
So I have a list of optional clothing items as checkboxes, there may be a greater number than the 5 below.
shoes, pants, skirt, socks, jacket //list of possible choices
A comma separated array is created in jquery of the chosen item. Let's say the following are chosen:
shoes, socks, jacket //array posted as $_POST['clothes']
In the db, each customer has these options in the clothes table with 'yes' or 'no' under the clothing items. However, the clothing item are named a bit differently but map out to the same options:
'clothes' table before insert
customer_id dress_shoes elegant_pants long_skirt ankle_socks biker_jacket
1 no yes no no no
With the $_POST['clothes'], I'm trying to loop through the array, updating the corresponding fields to 'yes', and the non corresponding fields to 'no' in the db. I have a hard time doing that.
'clothes' table after insert
customer_id dress_shoes elegant_pants long_skirt ankle_socks biker_jacket
1 yes no no yes yes
I did an array_intersect to get the items to mark as 'yes':
$clothesArray = array("shoes", "socks", "jacket"); // Posted clothes
$clothesArrayAll = array("shoes", "pants", "skirt", "socks", "jacket"); // All clothes
$common = array_intersect($clothesArrayAll,$clothesArray);
print_r($common);
Array ( [0] => shoes [3] => socks [4] => jacket )
I'm trying to somehow loop through the $clothesArrayAll, give a 'yes' to common clothes, and a 'no' to all others in the array. Then, I'm trying to update the 'clothes' table via PDO, setting each corresponding field to a 'yes' or 'no' in the most efficient way. I'm stuck after getting the common clothes array above and not sure how to proceed.
Can someone help me please?
Thank you!
I think you are on the right track. I would just add one additional array that contains the mappings of your fields, e.g.
$mappingArray = array('shoes' => 'dress_shoes', 'socks' => 'ankle_socks', ...);
With this array and the previous you can loop through and set your SQL accordingly based on the value of the $common field with the key in the $mappingArray
Edit with example (probably not the most optimized):
$finalArray = array();
foreach ($mappingArray as $key => $value) {
$finalArray[$value] = in_array($key, $common) ? 'yes' : 'no';
}
$finalArray will now have an yes/no statement for each value that matches your db table.
Edit to include PDO: I would actually update the above loop as follows:
$finalArray = array();
$sql = "INSERT INTO cloths (" . implode(",", array_values($mappingArray)) . ") VALUES (:" . implode(",:", array_values($mappingArray)) . ")";;
foreach ($mappingArray as $key => $value) {
$finalArray[":" . $value] = in_array($key, $common) ? 'yes' : 'no';
}
$q = $conn->prepare($sql);
$q->execute($finalArray);
Going on the fly with this one, so something like that...
Why not change your HTML field names to match your database names, set a default of 'no' in the atabase then...
$cols='INSERT INTO clothes ';
$values=' VALUES ';
$join='(';
foreach ($_POST as $key=>$val) {
$cols.=$join . $key;
$values=$join . ':' . $key;
$join=',';
}
$qry=$cols . ')' . $values . ')';
$stmt = $dbh->prepare($qry);
foreach ($_POST as $key=>$val) {
$stmt->bindParam(':' . $key, $_POST[$key]);
}
But you might want to check the posted names are valid column names - you can get the column names and types from the table using
DESC clothes;
This makes no sense!
The update query only actually updates if the value is an INT (yes it is defined as text).
The INSERT which has the same variables works with type of value!
mysql_query("UPDATE `atuam_mae`.`missoes` SET `mensagemdeuser` = $message WHERE `missoes`.`id` =$idmissao;");
mysql_query("INSERT INTO `atuam_mae`.`concelhos` (`id` ,`tempo` ,`userid` ,`concelho`) VALUES (NULL , CURRENT_TIMESTAMP , $user , '$message');");
That is because you are not enclosing your input variable in quotes:
"UPDATE `atuam_mae`.`missoes`
SET `mensagemdeuser` = '$message'
WHERE `missoes`.`id` = '$idmissao';"
NB. Don't do this and use prepared statements instead!
$stmt = $db->prepare('UPDATE `atuam_mae`.`missoes`
SET `mensagemdeuser` = :message
WHERE `missoes`.`id` = :id');
$stmt->execute(array(':message' => $message, ':id' => $idmissao));
I am not sure I understand what you meant but try putting values (right of the =) between single quotes this way:
mysql_query("UPDATE `atuam_mae`.`missoes` SET `mensagemdeuser` = '$message' WHERE `missoes`.`id` ='$idmissao';");