Confusion with writing query in cakephp - php

I just have a simple doubt in cakephp, it may be also silly.
Writing queries in cakephp:-
1.$output1 = $this->Modelname->query("Select * from tablename");
2.$output2 = $this->Modelname->query("Update tablename set .....");
When i execute the first query i.e $output1. It runs perfectly.
But wen i run $output2 it wont run correctly
What may be the problem ??

I would recommend you to use CakePHP methods to query against the database.
This way, it will be much more secure and things will be easier for you, more even if you have related models.
At first it can take a while to learn, but you will soon realize the advantages of it.
Your first query would be equivalent to:
$this->Modelname->find("all");
And your second one to something like:
// Update: id is set to a numerical value
$this->Modelname->id = 2;
$this->Modelname->save($this->request->data);

Related

PHP multiple MYSQL queries executed but only last one working

I am trying to run a couple of queries to swap sort order values within a database when up or down buttons are clicked however when he code below is executed on the 2nd query is ran.
if ($_POST['up']){
$sort_this = $_POST['sort'];
$sort_other = $_POST['sort'] - 1;
$sql_this = "UPDATE portfolio SET sort = $sort_this -1 WHERE sort = $sort_this";
mysqli_query($conn, $sql_this);
$sql_other = "UPDATE portfolio SET sort = $sort_other +1 WHERE sort = $sort_other";
mysqli_query($conn, $sql_other);
}
They both work perfectly fine on their own when i comment out the other, however when they are both display the problem is as above. I have also tried running it in a mysqli_multi_query however that didnt work either.
Any ideas?
Thanks
Given the limited amount of data my best guess would be that they DO both execute but that they're not doing what you think they should be doing.
Say $_POST['sort'] is the number 3, this means $sort_this is also 3.
The first query will go through the database and update all 3's to a 2.
$sort_other will be 3-1 (2) and so the second query will go through the database and update all 2's to a 3. Effectively undoing what the first query did. (and altering any other 2's to 3's)
You will never see the end result of the first query because the third query will overwrite all changes the first query made.
Also, simply pasting in a variable into a query like you're doing is bad practice. It is prone to SQL injection. You can avoid this by using prepared statements: http://php.net/manual/en/pdo.prepared-statements.php

MySQL Delete all selected rows in one request

Is it possible to SELECT specific rows and DELETE the selected result in ONE request?
$res = $Connection->query("SELECT * FROM tasks");
if($res->num_rows > 0){
while($row = $res->fetch_assoc()){ ...
The problem is that I have limited Number of queries to my SQL database and I want to minimize it as mush as possible.
You can't do that using the regular mysql-api in PHP. Just execute two queries. The second one will be so fast that it won't matter. This is a typical example of micro optimization. Don't worry about it. (So timing doesn't matter much)
For the record, since you are worried about the number of queries, it can be done using mysqli and the mysqli_multi_query-function.
P.S. - I haven't tried this, but since this mysql_multi_query is there in the documentation, it might help... :)
Both SELECT and DELETE need one request individually. And there is no SQL can do this work in the official documents.

Any value of separating a MySQL query into $query and $result?

I always see MySQL queries structured like this, even with the simplest of queries:
$query = "SELECT * FROM table_name WHERE id = '1'";
$result = mysql_query($query);
Is there any value, time or otherwise in doing the above over a simple one line query such as?
$result = mysql_query("SELECT * FROM table_name WHERE id = '1'";
I've always used the former, as when I started using PHP I thought it best to simply copy everyone else, however now that I'm working on a fairly large (relative to my other work) application, I could cut out a significant amount of arbitrary coding if there's really no difference.
Generally, I like separating them because I can easily do print $query; when I'm trying to figure out why my query won't work. It's mostly a matter of personal preference.
With the first, it's easier to log the SQL in case something went wrong (and it's easier to spot typos, like a missing bracket).
Actually there is no difference at all except for one thing. If you put your query in seperate variable then you can reuse that. If any changes occur in query you just need to edit the query in variable
You can always create a custom function that takes in a query and runs it, and pass additional optional arguments in case you want it to return the query, or log the query to track any issues etc.
Is there any value, time or otherwise in doing the above over a simple one line query such as?
sure, as MSpreij said, you can examine your query in case of error.
I always see MySQL queries structured like this, even with the simplest of queries:
$query = "SELECT * FROM table_name WHERE id = '1'";
$result = mysql_query($query) or trigger_error(mysql_error()." ".$query);
this simple construct will save you a dozen whines in stackoverflow "what does it mean mysql_fetch_array(): supplied argument is not a valid MySQL result"
notice the additional part. This is called programming.
It will print your query automatically, in case of error, along with mysql error message. Or log it into error log in a live server with appropriate settings.
Without writing print $query; manually.
However, both methods are ugly as hell.
One should never use raw API functions at all.
It's ugly, unmaintainable, bloated and repetitive.
One should develop a library, a function to make a call more intelligent and less repetitive
$data = mydb_get_row("SELECT * FROM table_name WHERE id = 1");
having all the processing inside. with error handling, query logging, parameter checking and api functions calling.
yet as a true one-liner, not a silly one you were trying to achieve.

Is there a better way of getting an item from a MySQL db?

I'm fairly novice with SQL (reading right now). I'm wondering if there is a better way in PHP to get a MySQL data item than the following:
$sql = "SELECT `topic_id` from `topics` WHERE `user_id` = ".$userId." AND `topic` = ".$topic.";";
$topicRow = mysql_query($sql);
$row = mysql_fetch_array($topicRow);
$topicId = $row['topic_id'];
I mean, 4 variables were created to get 1 item. Am I doing something incorrectly?
Thank you
The amount of vars is not a real issue, you could put the sql-string in your query if you want, but you're not really winning anything measurable. Please do not look for efficiency there. While the answers of #genesis and #patapizza are correct as far as I can see, they do not help you in any way to better your code, but only make it less readable.
You should look into parametereized queries (take a look at using PDO): You should split your content ($userId) and your SQL-command.
An example from the manual:
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->execute(array(150, 'red'));
$red = $sth->fetchAll();
You don't have to escape the various things you put in your query, so you're save from injection.
(ow, and coincidently, only using 2 variables.. jeeeej :) )
Unless you have not SQL-escaped $userId and $topic your code is susceptible to SQL-injection. I would also use the PDO API instead which is database management system independent.
http://php.net/manual/en/book.pdo.php
You could always use a database abstraction layer, like ADOdb.
The thing is, you do not want to constantly get involved into escaping variables, and query concatenation is something which shouldn't be done in many places in the code. Having all that, the best thing you can do, is Really, using something like ADOdb, or make something of your own, in case ADOdb doesn't respond to your needs.
It is absolutely incorrect, from an architect's point of view, to mix logic, real program logic, with stuff like technical means of getting at your data (open connection, define command, get result, read result, etc). In that logic you just have to Get your data. You don't need to see a database connection in your logic.

Dynamic SQL queries in code possible?

Instead of hard coding sql queries like Select * from users where user_id =220202 can these be made dynamic like Select * from $users where $user_id = $input.
Reason i ask is when changes are needed to table/column names i can just update it in one place and don't have to ask developers to go line by line to find all references to update. It is very time consuming. And I do not like the idea of exposing database stuff in the code.
My major concern is load time. Like with dynamic pages, the database has to fetch the page content, same way if queries are dynamic first system has to lookup the references then execute the queries, so does it impact load times?
I am using codeignitor PHP.
If it is possible then the next question is where to store all the references? In the app, in a file, in the DB, and how?
---EDIT:
Even better: Can the SQL query itself be made dynamic? I can just reference $sqlA instead of the whole query? This way if I have to re-write the query I can just update 1 file.
Because you are using Codeigniter, I would reccomend utilizing the Active Record Class to accomplish what you are trying to do.
The active record class enables you to build queries dynamically in steps allowing you to build them logically. So to take your example using active record...
( this could be accomplished with less code, I'm just trying to illustrate Active Record )
$this->db->select('*');
$this->db->from($table);
$this->db->where($user_id, $input);
and so to show what I mean about building the query logically, you can build whatever logic you want INTO the query building process. Lets say you have a $limit variable that you set if you want to limit the number of results you get. BUT if it isn't set (or NULL) you don't want to set the limit clause.
if ( $isset($limit) ) {
$this->db->limit($limit);
}
and now to execute your query now that it has been built
$query = $this->db->get();
Then just deal with $query with your database class just like you would any other CodeIgniter query object.
Of course you can, if that's what you wish. I'd rather recommend you taking more time to design you database but changes in the schema are inevitable in the long run.
I don't think load time would be an issue with this because ussually the bottleneck in this applications is in the database.
Finally my recommendation is to save this in a file just by declaring the column names as php variables
It depends on the database driver(s) you are using. The old PHP database drivers did not support placeholders (PHP 3.x). The modern (PDO) ones do. You write the SQL with question marks:
SELECT * FROM Users WHERE User_ID = ?
You then provide the value of the user ID when you execute the query.
However, you cannot provide the column name like this - only values. But you could prepare a statement from a string such as:
SELECT * FROM Users WHERE $user_id = ?
Then you provide the value at execute time.
mysql_query() takes a string and it doesn't need to be a constant string, it can be a variable.
$SQL = "SELECT foo FROM bar b";
SQLSet = mysql_query($SQL);
Aa you can see, you can use ordinary string manipulation to build your whole SQL query.
$SQL="SELECT * FROM MyTable";
$BuzID = 5;
$Filter = "Buz=".$BuzID;
if (is_numeric($BuzID)) SQL .= " WHERE ".$Filter;
SQLSet = mysql_query($SQL);
This will expand to "SELECT * FROM MyTable WHERE Buz=5" if $BuzID is set to any number.
If not the statement will just be "SELECT * FROM MyTable"
As you can see, you can build very complex SQL statements on the fly without need of variable support in the SQL server.
IF you want constants such as database name, user login, you can but them in a separate include located outside the public directory.
SecretStuff.inc.php
$__DatabaseName = "localhost";
$__UserName = "DatabaseAccess";
$__Password = "E19A4F72B4AA091C6D2";
Or have the whole PHP database connection code in the same file.

Categories