I'm really new to SQL and looked around the web for help on incrementing values but couldn't find something that works for me. What I'm trying to do is increment the value of user_posts when a reply/topic is posted. The user_posts is in users (forums>users>user_posts). I don't know how to get the specific user and then add to the value of his/her posts. I'm working off of a very small and basic example, which is how I have posts working. I was thinking I could add it to the SQL where the topic is sent to the DB but, like I said, can't figure out how. I don't really have any code to provide to start with because I really don't know where to start. I believe it uses UPDATE, but that's all I can guess. If you aren't quite sure what it is I want even after reading all of this, ask and I'll try to clarify.
Here's what it looks like with part of the working post code and a suggested code that doesn't seem to work.
VALUES ('" . $_POST['reply-content'] . "',
NOW(),
" . mysql_real_escape_string($_GET['id']) . ",
" . $_SESSION['user_id'] . ");
UPDATE users SET user_posts=1 WHERE user_id=1";
You can write
UPDATE Users
SET PostCount = PostCount + 1
WHERE UserId = #id
Something like: select postcount from users where user_id = <userid>; followed by update users set postcount=<new_postcount> where user_id = <userid>;. Some details: http://www.w3schools.com/sql/sql_update.asp
I wouldn't worry about optimizing your queries to your database until you experience problems handling your load. :)
Related
I have a list of Products with a field called 'Title' and I have been trying to get a list of initial letters with not much luck. The closes I have is the following that dosn't work as 'Distinct' fails to work.
atoz = Product.objects.all().only('title').extra(select={'letter': "UPPER(SUBSTR(title,1,1))"}).distinct('letter')
I must be going wrong somewhere,
I hope someone can help.
You can get it in python after the queryset got in, which is trivial:
products = Project.objects.values_list('title', flat=True).distinct()
atoz = set([i[0] for i in products])
If you are using mysql, I found another answer useful, albeit using sql(django execute sql directly):
SELECT DISTINCT LEFT(title, 1) FROM product;
The best answer I could come up with, which isn't 100% ideal as it requires post processing is this.
atoz = sorted(set(Product.objects.all().extra(select={'letter': "UPPER(SUBSTR(title,1,1))"}).values_list('letter', flat=True)))
I found this response very helpful
How to write join query in Volusion API
What I'm looking for is a way to add my own .SQL and .XSD files to the /vspfiles/schema/Generic folder and be able to pass parameters to it. Does anyone know if that's possible.
A very basic example of the SQL would be something like this...
select * from Orders where order_id = "-ORDERID-"
...and I'd be able to pass in the "-ORDERID-" as a variable.
Or even better the SQL file would just be this "-SQL-" and I could pass in the entire SQL string myself. Thanks!
Thanks user357034 for getting me here (I'd "up" your answer but I'm new and don't have any reputation). I wanted to post the code I used in case others run into this. And also get any feedback if you see anything that looks goofy here.
First, I created an ASP file like so
Dim orderid
Dim status
orderid = Request.QueryString("orderid")
status = Request.QueryString("status")
sql = " update Orders " & _
" set OrderStatus = '" + status + "' " & _
" where Orderid in (" + orderid + ") " ;
set fs=Server.CreateObject("Scripting.FileSystemObject")
set f=fs.OpenTextFile(Server.MapPath("./MY_FILE.sql"),2,true)
f.WriteLine(sql)
f.Close
set f=Nothing
set fs=Nothing
I FTPed that up to the "generic" folder on Volusion.
Next, in PHP, I call this file, similar to this...
$asp = file("http://MY_SITE/v/vspfiles/schema/generic/MY_FILE.asp?
orderid=11,12&status=Processing");
foreach ( $asp as $line )
{
echo ($line);
}
NOTE: I already FTPed an XSD file to the same folder with the same name, like MY_FILE.xsd.
And finally, I make a web service call to my service, like this...
$url = "http://MY_SITE/net/WebService.aspx?
Login=XXXX&EncryptedPassword=YYYYY&API_Name=Generic\MY_FILE"
Works great. I go into the Volusion admin site, look at the Orders 11 and 12, and they were updated. I'm using this method for several areas in Volusion where their API is lacking. Thanks!
While technically one could pass in text comprised of a complete SQL query, however I would strongly caution against such practice as it would open up your site to malicious activity and/or possible security issues. I would limit the scope to a specific query and only allow one or more parameters to be used.
To accomplish this you have to create an custom ASP page in Volusion that would gather the parameters from the user, in your case "order id" and then insert them into the set SQL query, write that SQL query as a text file to the server in the correct location as shown in https://stackoverflow.com/a/29134928/357034 and then execute the query. All this is done in the custom ASP page.
UPDATE: If you just want a simple order id query with all fields returned you don't even have to use the the SQL method as Volusion already has a built in method to return this data. You just have to use a custom ASP page to insert the order id parameter and then execute the URL with the parameter attached. In your ASP page you would insert the order id in place of the xxxxx
http://www.yoursiteurl.com/net/WebService.aspx?Login=name#yoursiteurl.com&EncryptedPassword=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxC&EDI_Name=Generic\Orders&SELECT_Columns=*&WHERE_Column=o.OrderID&WHERE_Value=xxxxx
Important Edit: There was not a programming error
That was a mistake by me and resulted to the problem. Please read the problem below:
I want to update user's last login's timestamp after I see that the user has logged in with below login() function at user_model.php.
public function login($username, $password)
{
$this->db->select('id, username, email, type, language, lastlogintimestamp');
$this->db->from('user');
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->limit(1);
$result = $this->db->get();
if ($result->num_rows() > 0)
{
$this_user = $result->first_row();
$this->db->query(
'UPDATE `user` SET `lastlogintimestamp` = ? WHERE `id` = ? LIMIT 1',
array(time(), $this_user->id)
);
return $this_user;
}
return FALSE;
}
After the user has logged in successfully, $result->first_row() is stored into $this_user variable and after that I update the lastlogintimestamp.
So it's obvious that the old value of lastlogintimestamp should be returned.
THE PROBLEM is that very strangely I see that the new value is returned!!!
Very simple: Where I was seeing the result, was because of a very separate query like SELECT * FROM user.
There, I was seeing a list of users with their own lastlogintimestamps.
It's clear that I was seeing the updated lastlogintimestamps.
Anyway I should thank Prix for helping me find the problem via the comments. I think that the best I can do now with this question, is voting for it be close.
Considering the comments of my question, I got what I was doing wrong.
I should again thank #Prix for putting me in the right direction as he said in the last comment. (Read THIS comment and the next 3 ones)
I voted to close the question and accept it as an answer to be unanswered not.
Is there a way to update every email address in MySQL with regexp? What I want to do is to change something#domain.xx addresses to something#domain.yy. Is it possible to do with SQL or should I do it with PHP for example?
Thanks!
You can search for a REGEXP with MySQL, but, unfortunately, it cannot return the matched part.
It's possible to do it with SQL as follows:
UPDATE mytable
SET email = REPLACE(email, '#domain.xx', '#domain.yy')
WHERE email REGEXP '#domain.xx$'
You can omit the WHERE clause, but it could lead to unexpected results (like #example.xxx.com will be replaced with #example.yyx.com), so it's better to leave it.
UPDATE tableName
SET email = CONCAT(SUBSTRING(email, 1, locate('#',email)), 'domain.yy')
WHERE email REGEXP '#domain.xx$';
I would rather do it with PHP, if possible. Mysql unfortunately does not allow capturing matching parts in regular expressions. Or even better: you can combine the two like this, for example:
$emails = fetchAllDistinctEmailsIntoAnArray();
# Make the array int-indexed:
$emails = array_values($emails);
# convert the mails
$replacedEmails = preg_replace('/xx$/', 'yy', $emails);
# create a new query
$cases = array();
foreach ($emails as $key => $email) {
# Don't forget to use mysql_escape_string or similar!
$cases[] = "WHEN '" . escapeValue($email) .
"' THEN '" . escappeValue(replacedEmails[$key]) . "'";
}
issueQuery(
"UPDATE `YourTable`
SET `emailColumn` =
CASE `emailColumn`" .
implode(',', $cases) .
" END CASE");
Note that this solution will take quite some time and you may run out of memory or hit execution limits if you have many entries in your database. You might want to look into ignore_user_abort() and ini_set() for changing the memory limit for this script.
Disclaimer: Script not tested! Do not use without understanding/testing the code (might mess up your db).
Didn't check it, since don't have mysql installed, but seems it could help you
update table_name
set table_name.email = substr(table_name.email, 0, position("#" in table_name.email) + 1)
+ "new_domain";
PS. Regexp won't help you for update, since it only can help you to locate specific entrance of substring in string ot check whenever string is matches the pattern. Here you can find reference to relevant functions.
Forgive me if I could have any sort of fundamental error here. I'd imagine there's something simple I'm missing. I'm looking to store Twitter updates in a database with only a few fields: an auto-increment index, the time posted, the actual status update & the user id the update is in reply to.
I'm simply storing this last field so I can provide a method of filtering out replies.
But it appears that my SQL code is throwing an error. As of this writing, the SQL properly inserts the two most recent updates, which are both replies to another user and, therefore, have data in the in_reply_to_user_id field. But on the third update, which is not in reply to anyone, I get the following error:
Error Number: 1064
You have an error in your SQL syntax;
check the manual that corresponds to
your MySQL server version for the
right syntax to use near ')' at line 1
INSERT IGNORE INTO updates (time,
status, postid, reply) VALUES
(1260070319, 'I guess Johnny Cash knew
what he was talking about in that \"A
Boy Named Suh\" song. That guy is both
fast and mean.', '6389320556', )
Twitter's API states no default value for this parameter. I tried the same query with the "favorited" parameter, and it correctly labeled each row with "false" in my database. So I'm assuming my problem is with inserting an empty string.
For what it's worth, here is my CodeIgniter method:
function insert_tweet($tweet){
foreach($tweet as $t) {
$when = strtotime($t->created_at);
$status = $t->text;
$postid = $t->id;
$reply = $t->in_reply_to_user_id;
$sql = 'INSERT IGNORE INTO updates (time, status, postid, reply) VALUES (?, ?, ?, ?)';
$this->db->query($sql, array($when, $status, $postid, $reply));
}
}
Any help you could give would be great! I hope I've provided enough information!
More info: I should also note that CodeIgniter is throwing the following error:
A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass
could not be converted to string
Filename: database/DB_driver.php
Line Number: 598
In the off chance that this proves some sort of CI idiosyncrasy to be at fault.
I don't know php but in asp.net style pseudo code i would do this...
$this->db->query($sql, array($when, $status, $postid, string.IsNullOrEmpty($reply) ? null : $reply));
Hopefully you can adapt, just need to deal with the empty parameter.
I don't speak codeigniter, but I can tell you how to fix your problem.
You have two options
Check is the string empty, if so, instead of having a blank value, put in the null keyword.
Check is the value empty, if so, leave that column out of the insert statement's cloumns and values.
Hope this helps
I'm not sure about codeigniter (never used it) but I know that you will need to get the null value to appear as NULL
function insert_tweet($tweet){
foreach($tweet as $t) {
$when = strtotime($t->created_at);
$status = $t->text;
$postid = $t->id;
$reply = (is_null($t->in_reply_to_user_id) ? 'NULL' : $t->in_reply_to_user_id);
$sql = 'INSERT IGNORE INTO updates (time, status, postid, reply) VALUES (?, ?, ?, ?)';
$this->db->query($sql, array($when, $status, $postid, $reply));
}
}
I'm not sure if that will produce the desired SQL:
INSERT IGNORE INTO updates (time, status, postid, reply) VALUES (1260070319, 'I guess Johnny Cash knew what he was talking about in that \"A Boy Named Suh\" song. That guy is both fast and mean.', '6389320556', NULL)
edit Also make sure that the field in the database can be null.
Hope this helps..
Why not alter the last column and make it default to NULL?
When you want to insert some record without this field you just ignore it in the 'INSERT' statement.
And be sure not to put a pending comma between the last column value and the right parenthisis.
:)
You're coming from the CodeIgniter forums right? I think the issue is coming from your Twitter library. Can you post that code? For somereason, it's returning a NULL status as an Object, which it shouldn't do.
Hey guys, the answers here seemed to be close, but no cigar. I got some help from the great folks on the CodeIgniter forums, and here's what I came up with:
$reply = (is_null($t->in_reply_to_user_id) || is_object($t->in_reply_to_user_id) ? ‘NULL’ : $t->in_reply_to_user_id);
Essentially, like Zack said, it is returning the empty field from the Twitter API as an empty object instead of null. So I needed to check if this is either null or an object, then return NULL. And if not, return the user_id string.
Thanks a ton for your help!