mySQL Query - Not inserting - php

I have a problem (obviously), the sql query is not successfully inserting into the table;
This is my code:
if (isset($_POST["newpost"])) {
$sqlSTR = "SELECT idPhoto FROM tblhomepagephotos order by idPhoto desc LIMIT 1 INTO #myID;
INSERT INTO tblhomepagetext(idText, hpText)
VALUES (#myID, '" . $_POST["newpost"] . "')";
echo $sqlSTR;
$result= mysql_query($sqlSTR);
}
The echo for the sqlSTR is:
SELECT idPhoto FROM tblhomepagephotos order by idPhoto desc LIMIT 1 INTO #myID;
INSERT INTO tblhomepagetext(idText, hpText) VALUES (#myID, 'Text here')
Now the problem is that it worked perfectly and inserts into tblhomepagetext perfectely when executed from mySQL Workbench, but doesn't work when executed from the website.
Any ideas of why?
I thought it might be due to some PHP conflict where theres the ';' in the sql query.

Your using the INSERT INTO SELECT syntax incorrectly, you have the order swapped around. It should be more like:
INSERT INTO Customers (CustomerName, Country)
SELECT SupplierName, Country FROM Suppliers
WHERE Country='Germany';
http://www.w3schools.com/sql/sql_insert_into_select.asp
However, I suspect you don't require INSERT INTO SELECT at all. If you simply need to INSERT into a table then the syntax is more like this:
INSERT INTO Customers (CustomerName, City, Country)
VALUES ('Cardinal', 'Stavanger', 'Norway');
http://www.w3schools.com/sql/sql_insert.asp
I suggest you read through those links before proceeding
Edit: Also that semi colon in your example should not be there, that is separating the command in two. This is the reason mySQL workbench can perform the query. It is literally performing two queries sequentially. First it selects some value from your tblhomepagephotos table, then it inserts into tblhomepagephotos. You need to combine the queries as I show above. Then, PHP will be able to perform the single query.
Edit2:
There are many issues with your code its hard to tell whether you need INSERT INTO SELECT or not because I can't figure out your logic.
What I suggest you do is read more examples of howto perform basic CRUD interaction with your database (http://en.wikipedia.org/wiki/Create,_read,_update_and_delete). I suggest you might require to first SELECT your photo details, THEN insert into the tblhomepagetext table. but firstly just see if the below code works. BTW, at very least you should use mysql_real_escape_string() as below when inserting a value via post into your database with mysqli . better yet is to use something like PDO, or learn an entire PHP framework such as Cake, Codeigniter or Zend Framework. These are all solutions to help with exposure to SQL Injection
From your latest comments, here is a solution i think your after:
// PERFORM Base64 PHOTO INSERT QUERY HERE
// (I assume your already doing this as you mention from your Base64 comment.)
// Directly following the insert image query, you need to use the magical command of `mysqli_insert_id()`.
// This will grab the latest inserted Database ID from the previous INSERT command.
$latest_photo_id = mysqli_insert_id();
// now that we have the latest photo ID we can insert into our homepage table
if (isset($_POST["newpost"])) {
$your_id = 1; // put a ID from your photo table here.
$sqlSTR = "INSERT INTO tblhomepagetext(idText, hpText)
VALUES (".$latest_photo_id.", '" . mysql_real_escape_string($_POST["newpost"]) . "')";
echo $sqlSTR;
$result= mysqli_query($sqlSTR);
}

Related

How can I use an SQL query's result for the WHERE clause of another query?

Okay, basically I have a table that contains statements like:
incident.client_category = 1
incident.client_category = 8
incident.severity = 1
etc.
I would like to use the contents from this table to generate other tables that fulfill the conditions expressed in this one. So I would need to make it something like
SELECT * FROM incident WHERE incident.client_category = 1
But the last part of the where has to come from the first table. Right now what I'm trying to do is something like
SELECT * FROM incident WHERE (SELECT condition FROM condition WHERE id = 1)
id = 1 stands for the condition's id. Right now I only want to work with ONE condition for testing purposes. Is there a way to achieve this? Because if there isn't, I might have to just parse the first query's results through PHP into my incident query.
Table schemas:
Engineering Suggestion - Normalize the DB
Storing a WHERE clause, like id = 10, in a field in a MySQL table, is not a good idea. I recommend taking a look at MySQL Normalization. You shouldn't store id = 10 as a varchar, but rather, you should store something like OtherTableid. This allows you to use indices, to optimize your DB, and to get a ton of other features that you are deprived of by using fields as WHERE clauses.
But sometimes we need a solution asap, and we can't re-engineer everything! So let's take a look at making one...
Solution
Here is a solution that will work even on very old, v. 5.0 versions of MySQL. Set the variable using SET, prepare a statement using PREPARE, and execute it using EXECUTE. Let's set our query into a variable...
SET #query = CONCAT(
"SELECT * FROM incident WHERE ",
(SELECT condition FROM condition WHERE id = 1)
);
I know for a fact that this should work, because the following definitely works for me on my system (which doesn't require building any new tables or schema changes)...
SET #query = CONCAT("SELECT id FROM myTable WHERE id = ", (SELECT MAX(id) FROM myTable));
If I SELECT #query;, I get: SELECT id FROM myTable WHERE id = 1737901. Now, all we need to do is run this query!
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
Here we use a prepare to build the query, execute to execute it, and deallocate to be ready for the next prepared statement. On my own example above, which can be tested by anyone without DB schema changes, I got good, positive results: EXECUTE stmt1; gives me...
| id | 1737901 | .
here is one way to achieve your goal by using what is called dynamic sql, be ware that this works only select from condition table returns only one record.
declare #SQLSTRING varchar(4000)
, #condition VARCHAR(500) -- change the size to whatever condition column size is
SELECT #condition = condition
FROM
condition
WHERE
id = 1
SET #SQLSTRING= 'SELECT * FROM incident WHERE ' + #condition
exec sp_executesql(#SQLSTRING)
Since you have also tagged the question with PHP, I would suggest using that. Simply select the string from the condition table and use the result to build up a SQL query (as a string in PHP) including it. Then run the second query. Psudo-code (skipping over what library/framework you re using to call the db):
$query = "select condition from condition where id = :id";
$condition = callDbAndReturnString($query, $id);
$query = "select * from incident where " . $condition;
$result = callDb($query);
However, be very careful. Where and how are you populating the possible values in the condition table? Even how is your user choosing which one to use? You run the risk of opening yourself up to a secondary SQL injection attack if you allow the user to generate values and store them there. Since you are using the value from the condition table as a string, you cannot parametrise the query using it as you (hopefully!) normally would. Depending on the queries you run and the possible values there as conditions, there might also be risk even if you just let them pick from a pre-built list. I would seriously ask myself if this (saving parts of SQL queries as strings in another table) is the best approach. But, if you decide it is, this should work.

Inserting values into a table under conditions

Im trying to insert two values into a table if one condition is met and another is not met.
I've found a tutorial on the matter but i can't seem to get it to work.
The tutorial explains how to create a simple PHP like button, and has two tables, articles and articles_likes.
articles has two columns: id and title.
articles_likes has three columns: id, user and article.
The code in the tutorial looks like this:
$db->query("
INSERT INTO articles_likes (user, article)
SELECT {$_SESSION['user_id']}, {$id}
FROM articles
WHERE EXISTS (
SELECT id
FROM articles
WHERE id = {$id})
AND NOT EXISTS (
SELECT id
FROM articles_likes
WHERE user = {$_SESSION['user_id']}
AND article = {$id})
LIMIT 1
");
Now first of all, im using PDO with $query = $pdo->prepare(" .. "); and question marks plus bindValue() to avoid SQL injections, and all that is working fine with other SQL statements, but this one does not seem to work.
I've googled the INSERT INTO .. SELECT .. FROM syntax, and W3schools explains it as copying values from one table into another one. So how is this even working in the tutorial? articles has a completely different structure, and he is inserting $variables into the SELECT statement.
Can anyone explain why this works in the first place, and how it would work in PDO?
Edit:
Here is my own code (I've added $value because my code is for a binary rating instead of a like):
global $pdo;
$query = $pdo->prepare("
INSERT INTO quote_ratings (user_ip, quote_id, value)
SELECT ?, ?, ?
FROM posts
WHERE EXISTS (
SELECT id
FROM posts
WHERE id = ?)
AND NOT EXISTS (
SELECT id
FROM quote_ratings
WHERE user_ip = ?
AND quote_id = ?)
LIMIT 1
");
$query->bindValue(1, $user_ip);
$query->bindValue(2, $quote_id);
$query->bindValue(3, $rating);
$query->bindValue(4, $quote_id);
$query->bindValue(5, $user_ip);
$query->bindValue(6, $quote_id);
$query->execute();
Some kind of nested SQL queries did not get bind properly and something is left by the PDO parser during the processing of query. Also there is no way to see if the the final query generated by PDO.
I will recommend to use Mysqli library to use in such scenarios. I usually encounter such issues during complex joins or executions of custom triggers. If you want to go ahead with object oriented code you can use MySQLi Class or also you could use simple procedural approach.
Atul Jindal
I i completely agree that PDO is good choice to avoid sql injections but, you know at such situations you are unable to debug your queries. But if you use mysqli wisely and properly check sql injections when you input, then there will not be a problem.
I've found the problem: PDO, by default, uses unbuffered queries. This for some reason makes the request impossible to parse. So the mode has to be changed for this request:
$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
and everything works fine from then on!

PHP Conditional vs MySQL Conditional

I am trying to display the data from 'table' if a key inputted by the user is found in the database. Currently I have it set up so that the database checks if the key exists, like so:
//Select all from table if a key entry that matches the user specified key exists
$sql = 'SELECT * FROM `table` WHERE EXISTS(SELECT * FROM `keys` WHERE `key` = :key)';
//Prepare the SQL query
$query = $db->prepare($sql);
//Substitute the :key placeholder for the $key variable specified by the user
$query->execute(array(':key' => $key));
//While fetched data from the query exists. While $r is true
while($r = $query->fetch(PDO::FETCH_ASSOC)) {
//Debug: Display the data
echo $r['data'] . '<br>';
}
These aren't the only SQL statements in the program that are required. Later, an INSERT query along with possibly another SELECT query need to be made.
Now, to my understanding, using WHERE EXISTS isn't always efficient. However, would it be more efficient to split the query into two separate statements and just have PHP check if any rows are returned when looking for a matching key?
I took a look at a similar question, however it compares multiple statements on a much larger scale, as opposed to a single statement vs a single condition.
#MarkBaker Join doesn't have to be faster than exists statement. Query optymalizer is able to rewrite the query live if it sees better way to accomplish query. Exists statement is more readable than join.
Fetching all the data and making filtering directly in PHP is always bad idea. What if your table grow up to milions of records? MySQL is going to find the best execute plan for you. It will automaticaly cache the query if it is going to improve performance.
In other words, your made everything correctly as far as we can see your code now. For futher analyse show us all of your queries.

How to insert with a where from another database?

How do I insert using sql when my data is on one table and my where is on another. Here is the code:
$sql = "INSERT INTO user_can (online_id) VALUES ('$online') WHERE user.online = 'online'";
mysql_query($sql);
I seem to be getting errors when trying to insert, the insert does not happen. It looks like I am messing up with my where code. Does anybody know how I can insert my data?
You're mixing parts of one statement type with parts of another. The SQL needs to be something like:
INSERT INTO user_can (online_id) SELECT online_id FROM user WHERE online = 'online';
The INSERT ... VALUES ... format is for providing explicit values in the SQL. Further Information about INSERT syntax.

PHP MySQL Insert fail after DELETE

I got two tables. One is account, another is Interest.
One account can have multi Interests and It can be edited.
Now, the process is deleting all Interest of this account then insert these insterests.
The QUERY IS:
"DELETE FROM Interests WHERE account_id='$id'"
"INSERT INTO Interests (account_id, interest_name) VALUES('$id', '$name')"
I use the both query when user update their account, but the insert is fail, there is nothing insert into the table (ps. the interests_id is auto_increment and this was be counted) but there is nothing new in the table. When I comment out the delete query. The insert will be successful.
Does any one know what can i do?
If you want to update your table records, you will do update operation.
like this:
UPDATE TABLE_NAME SET FIELD_NAME = 'VARIABLE_NAME'
WHERE PRIMERY_FIELD_NAME = 'VARIABLE_NAME' ;
you did not have to use these two queries, if you want to update data simply use the updat query of mysql.use this:
<?php
$query = "UPDATE Interests SET interest_name = '".$name."' WHERE account_id = '".$id."'" ;
mysql_query($query);
?>
If you want to update your table records then you may execute update operation. It like following
UPDATE Interests
SET
interest_name = '$name'
WHERE
accountno = '$id' ;
Try it. You may solve your problem by this way.
If you have queries failing, you should capture the error and see what went wrong. In all MySQL APIs for PHP, a query that fails returns a status code to indicate this. Examples of checking this status code are easy to find in the docs. But most developers fail to check the status.
Use transactions to ensure that both changes succeed together or neither are applied.
How to Decide to use Database Transactions
Definition of a transaction in MySQL: http://dev.mysql.com/doc/refman/5.5/en/glossary.html#glos_transaction
Syntax for starting and committing transactions in MySQL: http://dev.mysql.com/doc/refman/5.5/en/commit.html
You need to use InnoDB. MyISAM does not support transactions. http://dev.mysql.com/doc/refman/5.5/en/innodb-storage-engine.html
In PHP, you need to stop using the old ext/mysql API and start using MySQLi or PDO.
http://php.net/manual/en/mysqli.quickstart.transactions.php
http://php.net/manual/en/pdo.begintransaction.php
This happens because the query are treated as two single transaction, so the order of execution is not guaranteed.
The effect you are describing is because the insert is processed before delete, so the interests_id is auto-incremented properly, then the row is deleted by delete statement.
You should change the query logic or perform both queries in one single transaction.

Categories