Is it possible to store the results of a query in a table?
For example, I currently run a query using the following approach in php:
$sql = "SELECT id FROM mytable";
$query = pg_query($connection, $sql);
I then use pg_fetch_row() to access the result and return it to the web-browser. However, I would like to also store the results in a new table. I understand that I could run the same query twice so I would also have:
$sql_2 = "CREATE newtable AS SELECT id FROM mytable";
$query = pg_query($connection, $sql_2);
I was curious if there was a more efficient way of structuring my queries, so that I could both access the results, and insert the results into a table through just one query.
Unfortunately the CREATE TABLE command doesn't appear to accept a RETURNING clause, so that doesn't allow just having that command also return the results. So you're likely to need to do two queries.
You could swap the queries to create the new table first, then fetch the results by selecting out of that new table. Accessing that newly created table may be a bit faster than doing the initial query twice since postgres won't need to look over any irrelevant data. This would also guarantee that the same results appear in both places.
Related
I am building a reporting tool where an user can enter a SQL query and the tool will return the results in a CSV file. In addition to just writing to a CSV file, I also need to perform some additional logic here. So SELECT INTO OUTFILE will not work for me.
I know that executing arbitrary user provided SQL queries is bad, but this tool is going to be used only internally, so security shouldn't be a concern. Also I am limiting it to only select queries.
Now when I export the data in CSV format, I also want to output the column names of the query as the first row in the CSV file.
So my question is, is there a way to fetch the column names of a SQL query in PHP using PDO?
Mysql client tools like Sequel Pro are able to display the column names while displaying query results. So I am assuming that it should be possible, but I am not able to find it.
Here I am not writing full PDO connection code. You can use below code/logic to get the return column name.
$stmt = $conn->query("SELECT COUNT(*), first_column, second_column FROM table_name");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$columns = array_keys($row);
print_r($columns); // array(0 => COUNT(*), 1 => first_column, 2 => second_column)
The keys of the row result are the column names. You can display them like so:
$conn = mysqli_connect(YOUR_CONNECTION_INFO);
$result = mysqli_query($conn, YOUR_QUERY);
$row = mysqli_fetch_assoc($result);
foreach ($row as $key=>$value) {
echo $key;
}
You said security wasn't an issue since the code would only be used internally, but what happens if you create a new database user with limited rights and connect to the database using that user.
That way you can set up the rights as you want from your database and won't have to worry about users dropping tables.
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.
I'm using PHP PDO to access a sql database. There's a table with just two columns (ID and VALUE). I want to read that table into an array such that
$array[ID]=VALUE
I know how I can do it manually with a for loop or while loop going through one by oneā¦ but I was wondering if there's any better way of doing it.
You can use PDO::FETCH_KEY_PAIR constant
$sql = "select id, username from users limit 10";
$data = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
Spent the last few days researching this, but I think I'm just not getting it... I can usually do what I need to with PHP but am new to MySQL
I set up a MySQL database to hold some photos. The photo's are in separate galleries (gallery is denoted by a gallery field). The photo's are also indexed by an id number.
When displaying the photos (it all works perfectly up to now...), I would like to be able to jump to the next or previous photo in the gallery, but can't just us the next or previous id, as it could be from a different group (found that out the hard way ;)
from my research, I feel like I need to use this:
$sql = "SELECT id FROM gphoto WHERE gallery='$g' ORDER BY id DESC";
$query = mysqli_query($db_conx, $sql);
But $query doesn't seem to give me what I expect. It feels like $query it should contain an array if all id's which contain gphoto, and I should be able to just find my current id number, then jump one up or down, but when I try to read $query I get:
Cannot use object of type mysqli_result as array
I'm obviously misunderstanding something
Some people have suggested:
$result = mysqli_fetch_assoc($query);
I had tried this after reading the online manual extensively, but for some reason it only lists one item... in this case the last record.
If I run it as ASC, it lists the first. Should it be listing all records like I expect, or is it a different command?
C)
+1 for Fabio's response.
A good advice is to use PDO interface for accessing databases in PHP. It's a meaningful interface to construct, execute and fetch the results of your queries without the knowledge of the used db driver.
http://php.net/manual/en/book.pdo.php
You need to fetch data from database after executing your query to handle mysqli object you have just created
$query = mysqli_query($db_conx, $sql);
$result = mysqli_fetch_assoc($query);
Now you have the array you were looking for in your variable $result
if ($result = mysqli_query($db_conx, $query)) {
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
//mysqli_fetch_assoc fetches data by row
}
}
You are only getting 1 row, thats how mysqli_fetch_assoc works. If you want the entire result to be an array of the rows, use mysqli_fetch_all
I would recommend using PDO however like #ceadreak suggested.
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.