Is there any mysql syntax to stop the query from being append by user input? If the query is
SELECT *
FROM `username`
WHERE `type` = 'client'
END / LIMIT / whatever syntax here;
the query should stop at 'client' so if user try to add his own query by adding OR such as this:
SELECT *
FROM `username`
WHERE `type` = 'client'
OR 1 = 1;
it will not work. Thanks in advance.
I will assume that you are using PHP and that 'client' is received as a parameter via $_POST from the user. In this scenario I think that what you want to do is prevent is SQL injection. If so you should solve it by using mysql_real_escape_string() to sanitize your input parameters:
// This could be supplied by a user, for example
$type = $POST['type'];
// Formulate Query
// This is the best way to perform an SQL query
// For more examples, see mysql_real_escape_string()
$query = sprintf("SELECT * FROM username
WHERE type='%s',
mysql_real_escape_string($type));
// Perform Query
$result = mysql_query($query);
...
I took this sample from the mysql-query reference and adapted it for your needs.
Related
I'm trying to write a SQL query to update a field in a different database (Hosted on the same server with phpMyAdmin). I just want it to update the most recent row as the query will be run directly after a new user is added (on that new user). My goal output is to change the username field of this user to be the same as the email field of the user in the original database. The syntax error states
'syntax to use near 'FROM db2.users AS "data" WHERE db1.user.email =
...' at line 3'
I can't see where I'm going wrong - I saw another answer where a user said that mySQL does not support the FROM keyword, however I have not been able to find anywhere else that backs that up. This is what I currently have for my code:
UPDATE db1.user
SET username = data.username
FROM db2.users AS "data"
WHERE db1.user.email = data.email
AND db1.user.id = (
SELECT MAX(id)
FROM db1.user
)
LIMIT 1
If anyone knows where I'm going wrong with this it would be much appreciated!
In MySQL, the syntax would be:
UPDATE db1.user u JOIN
db2.users u2
ON u.email = u2.email JOIN
(SELECT MAX(u2.id) as max_id
FROM db1.user u2
) uu
ON uu.max_id = u.id
SET u.username = u2.username;
Notes:
It seems odd that you are not filtering by email to get the maximum id, but that is how your question is stated. Also, MySQL doesn't support LIMIT in multi-table UPDATE queries.
As in your SQL you are okay with using subqueries, I would suggest to try the following:
UPDATE
db1.user
SET
username = (
SELECT
data.email
FROM
db2.users AS "data"
WHERE
db1.user.email = data.email)
WHERE
db1.user.id = (
SELECT
MAX(id)
FROM
db1.user)
LIMIT 1;
I have an ActiveRecord query:
Post.where(users: [])
In Rails 5.1.1, this results in:
SELECT `posts`.* FROM `posts` WHERE (users = '[]')
but in Rails 5.2.2, this results in:
SELECT `posts`.* FROM `posts` WHERE 1=0
Does anyone know if this is expected behaviour in Rails 5.2 or a bug?
That is not a bug , 5.2.2 updated for remove SQL Injection problem.
SELECT `posts`.* FROM `posts` WHERE (users = '[]')
If you observe this query we have a SQL Injection problem , that is if you pass some query instead of value then it will pass . It's too dangerous. You can use below code for to retrieve data based on array objects with where condition.
ModelName.where('users IN (?)', [array of elements] )
Getting following error
SQLSTATE[HY000]: General error: 1390 Prepared statement contains too many placeholders
My query has become due to data in the table recently
SELECT
*
FROM
table
WHERE col1 = 'some-val'
AND col2 NOT IN ('va1', 'val2', 80k values... )
I am using Laravel 5.6
$data_will_be_skipped = OtherModel::select('code')
->where('col1', 0)
->orWhere('col2', 1)
->groupBy('col3')
->pluck('col3')->toArray();
$data_will_be_skipped is now approx 80k arrays
Model::where('col1', 'some-val')->whereNotIn('col2', $data_will_be_skipped)->get();
MySQL has a limit of 65,535 parameters in prepared statements.
Use a subquery instead:
$data_will_be_skipped = OtherModel::select('col3')
->where('col1', 0)
->orWhere('col2', 1);
Model::where('col1', 'some-val')
->whereNotIn('col2', $data_will_be_skipped)
->get();
No matter how many items u have in array to check in wherein
the simple way to do it
$data = model::whereRaw("id not in (".implode(',',$data_will_be_skipped).")")->get();
I just want to delete the row with the lowest ID.
I'm trying this:
$query = 'DELETE FROM PATH\TO\ENTITY ORDER BY id ASC LIMIT 1';
$query = $this->entityManager->createQuery($query);
$query->execute();
And getting this error:
[Syntax Error] line 0, col 53: Error: Expected end of string, got 'BY'
Maybe I'm using the wrong approach.
Any suggestions how to delete the entry with the lowest id in one database call?
As Kwido said, you miss the entity alias. But the query will still not be able to execute.
First, DQL does not support LIMIT expression. It is MySQL-specific feature, is not an ANSI SQL. Other platform drivers have an own implementations of this behavior, all of them provided by common interface: setFirstResult()/setMaxResult() of Query object.
Second, DQL does not support DELETE with ORDER BY clause (see language EBNF). It is non-standard feature too, but can not be implemented for other drivers, so Doctrine does not allow it.
If you need to execute this query, you will have to use a native SQL.
Define an alias for your entity as you use DQL. See: Doctrine - By DQL
$query = $this->entityManager->createQuery('SELECT e FROM MyEntity e ORDER BY e.id ASC');
$query->setMaxResults(1); // LIMITS 1
$entities = $query->getResult();
if (count($entities) > 0) {
$query = $this->entityManager->createQuery('DELETE FROM MyEntity e WHERE e.id = :identifier');
$query->setParameter("identifier", $entities[0]->getId());
$query->execute();
}
Replace entityAlias with the first letter of your entity classname, which is the most common practice with Doctrine.
// Edit - as #Timurib stated DQL doesn't know the LIMIT. Should've used setMaxResults.
// Edit2 - As ORDER BY is not supported by the DELETE statement, but only the WHERE clause. We're now using another query to return the identifier before deleting. See DQL - Statements
$query = 'DELETE FROM table ORDER BY id ASC LIMIT 1';
$stmt = $this->entityManager->getConnection()->prepare($query);
$stmt->execute();
You cannot delete or update from entityManager. First you have to select/find the entity from Repository and then remove it. My suggestion works for raw SQL query instead.
I would like to use a subquery inside a join, however Symfony2 throws the following error:
Here is my failed attempt:
$query = $em->createQuery(
'SELECT
sc.id AS id,
u.id AS userId,
u.username AS username,
sc_count.upvotes
FROM
myBundle:SuggestedCar sc
INNER JOIN myBundle:User u WITH sc.user_id = u.id
INNER JOIN ( SELECT sc1.user_id, COUNT(sc1.id) AS upvotes
FROM myBundle:SuggestedCar sc1
GROUP BY sc1.user_id
) sc_count WITH u.id = sc_count.user_id'
);
Basically I'm just joining 3 tables and the third one has a count. The query worked when executing it inside the database.
How would it be possible to use a SELECT statement inside a join? Is it a good idea to use raw SQL at this point?
The $em->createQuery() function is expecting DQL as the parameter, not SQL. If you want to execute a raw SQL statement, the syntax is different. You can do it like this:
$sql = "SELECT * FROM my_table";
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
for more on DQL or querying for objects, see Querying for Object. The biggest difference is DQL will return an object (based on your entity classes in Symfony). The method I posted above will just give you a PDO result. So if you execute raw SQL, don't expect to be able to use the result as an object.
If you want to use raw SQL and still have the result mapped to an object, you can look at the doctrine docs about Result set mapping. In my opinion, this is more work than necessary.