Adding 2 drop lists to associated table - mysql

I am having an issue trying to add the records using 2 drop lists.
I have a table called Urls which holds the details of url. I have a table called category populates a drop list, I have another table called publishers which populates another drop list.
$query = 'INSERT INTO url_associations (url_id, url_category_id, approved, url_publisher_id) VALUES ';
foreach ($_POST['types'] as $v){
$query .= "($uid, $v, 'Y', $k), ";
}
$query = substr ($query, 0, -2); // Chop off the last comma and space.
$result = #mysql_query ($query); // Run the query.
if (mysql_affected_rows() == count($_POST['types'])) { // Query ran OK.
echo '<p><b>Thank you for your submission!</b></p>';
$_POST = array(); // Reset values.
} else { // If second query did not run OK.
The code above allows me to addd data using the categories drop list but when I try to add the url_publisher_id as 'posters' as $k I keep getting errors in my parsing. If anyone can understand what I am trying to achieve your help would be welcomed

If the value of your $k variable is anything other than an integer or float you'll get an error because it needs quotes around it when you're building the SQL INSERT statement:
$query .= "($uid, $v, 'Y', '$k'), ";
Note: There are some major security problems in your example. If you put user input from $_POST into your SQL without escaping it you're giving the user the ability to run whatever SQL commands they want to run on your database.

I have added an extra array foreach ($_POST[posters] as $k)
//so it reads
'foreach ($_POST[types] as $v)
foreach ($_POST[posters] as $k) {`
and it has executed perfectly.
Thanks for your help.
Sean

Related

While loop only stores one value from #row=$sth->fetchrow_array() perl

sub completecheckout {
$cryptedcard = md5_hex($cardnum . $salt);
$grabcart = qq~select pid from cart where uid='$cookievalue'~;
$dbh = DBI->connect($connectionInfo, $user, $passwd);
$sth = $dbh->prepare($grabcart);
$sth->execute();
while (#row = $sth->fetchrow_array()) {
$insert = qq~insert transaction (uid, pid, cctype, ccnum)
values ('$cookievalue', '$row[0]', '$cardtype',
'$cryptedcard')~;
$dbh = DBI->connect($connectionInfo, $user, $passwd);
$sth = $dbh->prepare($insert);
$sth->execute();
}
$select = qq~select * from registered where id in
(select uid from transaction
where uid='$cookievalue')~;
$dbh = DBI->connect($connectionInfo,$user,$passwd);
$sth = $dbh->prepare($select);
$sth->execute();
#userinfo = $sth->fetchrow_array();
print header;
print qq~<html><head><title>YAY</title></head><body><p>CHECK MYSQL<p><p>#row</p></body></html>~;
}
I am trying to parse through the table cart and insert all the items associated with the user into a transaction table when they click the final checkout button. The above code will only insert the last row into the transaction table.
Here is code that inserts more than once, but does not work because $product is empty every other time.
sub completecheckout {
$cryptedcard = md5_hex($cardnum . $salt);
$grabcart = qq~select pid from cart where uid='$cookievalue'~;
$dbh = DBI->connect($connectionInfo,$user,$passwd);
$sth = $dbh->prepare($grabcart);
$sth->execute();
#cart = $sth->fetchrow_array();
foreach $product (#cart) {
$insert = qq~insert transaction (uid, pid, cctype, ccnum)
values ('$cookievalue', '$product', '$cardtype',
'$cryptedcard')~;
$dbh = DBI->connect($connectionInfo,$user,$passwd);
$sth = $dbh->prepare($insert);
$sth->execute();
}
$select = qq~select * from registered where id in
(select uid from transaction
where uid='$cookievalue')~;
$dbh = DBI->connect($connectionInfo,$user,$passwd);
$sth = $dbh->prepare($select);
$sth->execute();
#userinfo = $sth->fetchrow_array();
print header;
print qq~<html><head><title>YAY</title></head><body><p>CHECK MYSQL<p><p>#userinfo</p></body></html>~;
}
Can anyone explain why this happens? I have been using while loops with fetchrow_array throughout my script to create tables linked to databases.
Firstly, you need to get into the habit of formatting your code better. It really helps following logic flow if the formatting imitates the logic.
Secondly, please turn on use strict and get used to declaring variables as close to their point of use as possible.
Thirdly, don't use global variables. Your subroutine uses $cardnum, $salt, $cookievalue and several other variables which are (presumably) defined outside of the subroutine. They should all be passed into the subroutine as parameters.
I know from previous conversations that you have no interest in learning Perl, you're just trying to get through a course that your college insists on. So I should make it clear that all of the advice above has nothing to do with Perl. That is all good general advice for any programming language.
Now, the specific problems.
You're creating a new $dbh any time you want to run a database query. Why not just connect once and then reuse that variable. A single $dbh can support multiple queries executing at the same time.
As Matt has pointed out in the comments, you are overwriting $sth. As I said above, a $dbh can support multiple concurrent queries, but each query needs its own statement handle. So you might do something like:
my $dbh = DBI->connect(...);
my $select_sth = $dbh->prepare($select_sql);
$select_sth->execute;
while (my #row = $select_sth->fetchrow_array) {
my $insert_sth = $dbh->prepare($insert_sql);
$insert_sth->execute;
}
Notice how I've a) reused the same $dbh and b) declared the $insert_sth within the loop so it's only available for the shorted possible amount of time.
If you were interested in Perl, I'd also show you how to make your code more efficient by using bind points in your SQL and passing extra parameters to execute(). I'd also recommend moving raw HTML out of your program and using a templating engine. But I strongly suspect you wouldn't be interested.

DB Query on returning one value Laravel

Im using a simple query to pull the users in a table called users.
$users = DB::table('users')->get();
Then using a foreach loop to get the values , for example :
foreach ($users as $user)
{
return $user->email;
}
There is definitely 2 records in the DB Table, but it only returns one line. If i try to query a different table it does the same thing.
If i use the Query Log between the query
DB::enableQueryLog();
$users = DB::table('users')->get();
$result = DB::getQueryLog();
It returns the query and it looks fine
[{"query":"select * from `users`","bindings":[],"time":0.85}]
This table was created within PhpMyAdmin and not using the Artisan Migrate
Of course it so, cause you return from loop, use echo
foreach ($users as $user)
{
echo $user->email;
}
return statement inside the loop will behave like break for your case, this means breaking the loop.
You can use either:
DB::table('users')->select(['email'])->get();
or
DB::table('users')->get(['email']);
But its basics, you can easily find this stuff in docs https://laravel.com/docs/master/

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

Retrieve every model and return three values

I am looking for a way to retrieve all models in a database. Then loop through all of the models and read out the values for name, firstname and phonenumber.
So far I've gotten this and failed to go past it:
$searchModel = new EmployeeSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
I am then looking to implement those three values in a simple HTML table:
<tr><td>$firstname</td><td>$name</td><td>$phone</td></tr>
The table should be part of a PDF output, so ideally I would save it to a variable:
$html_table = '<tr><td>$firstname</td><td>$name</td><td>$phone</td></tr>';
I would need to get this for every model that fulfills the criteria of status = 'active' in the database.
So far I've only been able to get tables via gridView and not in a HTML template either.
You don't really need a data provider to achieve this, you could simply try :
$models = Employee::find()->where(['status'=>'active'])->orderBy('name ASC')->all();
foreach ($models as $model) {
echo "<tr><td>{$model->firstname}</td><td>{$model->name}</td><td>{$model->phone}</td></tr>";
}
Read more : http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#querying-data
You can get all models like this:
$employees = Employee::find()
->select('firstname, name, phone')
->asArray()
->where(['status'=>'active'])
->all();
This way you will get an array of arrays containing the 3 selected fields, so now you only need to use a foreach to loop through them and create the table:
$html = '<table>';
foreach($employees as $employee) {
$html .= '<tr><td>'.$employee['firstname'].'</td><td>'.$employee['name'].'</td><td>'.$employee['phone'].'</td></tr>';
}
$html .= '</table>'

Selecting MYSQL rows with same field names and adding a prefix

I'm trying to make a mysql query to select several tables and LEFT join them, however they all have same columns names 'user' etc. I want to rename all the fields in this manner . so I tried the following query
SELECT mod_backup_accounts . * AS account . * , mod_backup_subscriptions . *
FROM `mod_backup_accounts`
LEFT JOIN `mod_backup_subscriptions` ON `mod_backup_accounts`.subscription_id = `mod_backup_subscriptions`.package_id
However the mod_backup_accounts . * AS account . * makes it fail, is there a way to do this? so it would be names as account.
You cannot supply a shorthand to alias columns you must do it explicitly for each column name. In general anyway, it is typically recommended to name all columns explicitly in the SELECT list rather than using SELECT *, since it allows you to deterministically specify the column order, and protects you against accidentally pulling in a large BLOB later on if one ever gets added to the table ( or any other schema changes ).
SELECT
mod_backup_accounts.user AS account_user,
mod_backup_subscriptions.user AS subscription_user,
...
...
FROM
mod_backup_accounts
LEFT JOIN `mod_backup_subscriptions` ON `mod_backup_accounts`.subscription_id = `mod_backup_subscriptions`.package_id
I totally understand your problem about duplicated field names.
I needed that too until I coded my own function to solve it. If you are using PHP you can use it, or code yours in the language you are using for if you have this following facilities.
The trick here is that mysql_field_table() returns the table name and mysql_field_name() the field for each row in the result if it's got with mysql_num_fields() so you can mix them in a new array.
You can also modify the function to only add the "column." prefix when the field name is duplicated.
Regards,
function mysql_rows_with_columns($query) {
$result = mysql_query($query);
if (!$result) return false; // mysql_error() could be used outside
$fields = mysql_num_fields($result);
$rows = array();
while ($row = mysql_fetch_row($result)) {
$newRow = array();
for ($i=0; $i<$fields; $i++) {
$table = mysql_field_table($result, $i);
$name = mysql_field_name($result, $i);
$newRow[$table . "." . $name] = $row[$i];
}
$rows[] = $newRow;
}
mysql_free_result($result);
return $rows;
}