How to get affected row count on WordPress query? - php

This code is to use in WordPress plugin.
The following is my code I am using to insert data from CSV file to database:
$sql="LOAD DATA LOCAL INFILE '".$fileurl."' INTO TABLE ".$table_name."
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n' IGNORE 1 LINES (`first_name`,`last_name`, `email`, `mobile_phone`, `address_1`, `address_2`, `city`, `state`, `zip`, `about_us` );
";
$query = $wpdb->query($sql);
When I do this var_dump($query); it shows int(0), and data is successfully inserted in table. My question is how can I get number of inserted rows?

You can find the affected rows in your query using below.
$count = $wpdb->query($sql);
$count is your affected rows.

Very old question, I know, and perhaps this answer is trivially obvious, but posting in the hope it might be useful to someone who stumbled across it as I did.
In this particular case with LOAD DATA, one option might be to simply run an sql COUNT() before and after the LOAD DATA, and then take the difference:
$count_before = $wpdb->query("SELECT COUNT(*) FROM $table_name");
// LOAD DATA ...
$count_after = $wpdb->query("SELECT COUNT(*) FROM $table_name");
$new_rows = $count_after - $count_before;
I understand this may not work well if there is other simultaneous activity on the table; though you may be able to lock the table to prevent conflicting updates and to make the LOAD DATA even faster. You might be able to get this with $wpdb->affected_rows and that's also worth checking.
No doubt since it's 2 years ago since you asked this, you have any number of other working solutions; hopefully this is useful to anyone googling for a solution here.

Object $wpdb contains a lot of useful things. You can watch this by dump this object to see public properties.
One of them is what you search:
echo $wpdb->affected_rows;

You cannot get this information using a LOAD DATA statement with wpdb::query(). It doesn't understand the statement, so doesn't automatically fetch the number of affected rows. You can't get it yourself, either, because the necessary wpdb class properties (use_mysqli, dbh) are not public.

Related

Save mysql query into database

I am trying to allow users (In my place of work) to run a query, and if they choose, save it into a database so that they can just run it again later with a single click (Like if they are updating a database). I am having a problem with this, though. Simply running the query isn't an issue, but the query doesn't save correctly. The query is something like this:
LOAD DATA INFILE 'path/to/file/file.txt' INTO TABLE table FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n';
I can get it to save into the database correctly if I escape the backslashes when typing out the query, but that causes the query to run incorrectly on submit. I am wondering if there is a way that I can automatically escape backslashes. Or would it just be easier/better to separate the two features? If any more information is needed let me know, and thanks in advance.
I did some tinkering, and I got it. Here is the solution I came up with:
First, I used str_replace on the update.
$q = str_replace(array("\t", "\n"),array("\\t","\\n"), $_POST['update']);
Then, I prepared it as suggested.
if($stmt = $con->prepare("insert into queries (Query_Name, Query, Description) values (?, ?, ?);")){
$stmt->bind_param('sss', $qn, $q, $qd);
$stmt->execute();
$stmt->store_result();
$stmt->close();
}
Finally, I ran a mysqli_multi_query (because sometimes there is more than one query in a submission, which caused it to fail) to run the query(s) the user puts in.
$query = mysqli_multi_query($con, $q);
Thanks to everyone who offered suggestions!
You have to unescape the query before using it.
Create a method dedicated to run queries from the database like "myClass->unescapeAndExecute($escapedQueryFromDb);"

PHP, Postgres help using RETURNING

I think I understand how PostgreSQL and RETURNING works - I've found many, many resources. If I'm catching on, it would look something like
"INSERT INTO table (column2, column3) VALUES ('value1', 'value2') RETURNING id;"
However, I can't find anything that helps me access this via PHP. When I thought I figured it out, I tried
$new_id = pg_query($dbc, "INSERT INTO table (column2, column3) ".
"VALUES ('value1', 'value2') RETURNING id;");
return $new_id;
But it returns NULL. I also tried executing and declaring the variable separately with one query. After looking for hours for the solution, I've settled on a max(id) SELECT statement/function, but it's still bothering me. Any help is greatly appreciated.
I'm using Postgres 8.4 and PHP 5.3.
$new_id does not contain the id but it is a resource descriptor. You need to fetch the data from it as the query would be a SELECT, with pg_fetch_array($new_id) by example.
The RETURNING clause of PostgreSQL projects any fields of the inserted or modified rows ie INSERT|UPDATE … RETURNING id, field1, field2.

Fast Insertion in MySQL Table from php

I have to insert 50,000 to 16.000.000 rows in MySQL Table from php. It is taking at least 15-20 min to store in database.
To complete my project i have to do it more faster insertion. do anyone having any flexible opinion.
i am using this code
for($i=$d;$i<=$fd;$i++)
{ $j = $i-$d+1;
$sql1 = "INSERT INTO information(id, redirection, username, pc, date, time,
method,text, http, code, data, request, software) VALUES ('".$i."','"
.$_SESSION["redirection"][$j]."','".$_SESSION["username"]$j]."','"
.$_SESSION["pc"][$j]."','".$_SESSION["date"][$j]."','".
$_SESSION["time"][$j]."','".$_SESSION["method"][$j]."','"
.$_SESSION["text"][$j]."','".$_SESSION["http"][$j]."','"
.$_SESSION["code"][$j]."','".$_SESSION["data"][$j]."','"
.$_SESSION["request"][$j]."','".$_SESSION["software"][$j]."')";
mysql_query($sql1);
}
I agree with Cal. Try this:
$sql1 = "INSERT INTO information(id, redirection, username, pc, date, time,
method,text, http, code, data, request, software) VALUES ";
<?php
for($i=$d;$i<=$fd;$i++)
{
$j = $i-$d+1;
$sql1 .= "('".$i."','"
.$_SESSION["redirection"][$j]."','".$_SESSION["username"]$j]."','"
.$_SESSION["pc"][$j]."','".$_SESSION["date"][$j]."','"
.$_SESSION["time"][$j]."','".$_SESSION["method"][$j]."','"
.$_SESSION["text"][$j]."','".$_SESSION["http"][$j]."','"
.$_SESSION["code"][$j]."','".$_SESSION["data"][$j]."','"
.$_SESSION["request"][$j]."','".$_SESSION["software"][$j]."')";
if($i<=$fd){
$sql1 .= ", ";
}
}
mysql_query($sql1);
?>
In this case you will perform only one insertion instead multiple. Also, as variant, you can store your data into text file (.csv, for example) and then import it into your database. But this is exotic method.
Use extended insert syntax to insert multiple rows per statement:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
http://dev.mysql.com/doc/refman/5.5/en/insert.html
Another trick is to disable/delete indexes and enable/add them after all data has been inserted.
DISABLE KEYS;
INSERT ......
ENABLE KEYS;
If the table supports transactions (InnoDB), you can speed up bulk inserts by doing everything inside a single transaction. Query BEGIN TRANSACTION before all the inserts, and COMMIT after you're done.
Obviously, this is irrelevant if your table doesn't support transactions (MyISAM).
Prepared statements are another way to speed up bulk inserts (with added security benefits), but it's difficult to do that in a project that uses mysql_query() everywhere, so I'll leave that out.
You're not really clear what your limits are, and especially WHY. Other answers assume you are on some sort of time-schedule, and need the insert completed before a certain moment
But when we assume you want to have control over your program back as quickly as possible, but not neccesairily need the insert to be finished, you could use delayed inserts?
http://dev.mysql.com/doc/refman/5.5/en/insert-delayed.html
The DELAYED option for the INSERT statement is a MySQL extension to
standard SQL that is very useful if you have clients that cannot or
need not wait for the INSERT to complete. This is a common situation
when you use MySQL for logging and you also periodically run SELECT
and UPDATE statements that take a long time to complete.
When a client uses INSERT DELAYED, it gets an okay from the server at
once, and the row is queued to be inserted when the table is not in
use by any other thread.

mySQL table updates, but not fast enough for a select statement on the same page to access the updates - any ideas?

I am trying to write some code that updates a mysql table, and then selects out of that same table in the same page. However, I find that when I do the update query, then the select query, it does not recognize the changes. If, however, I refresh the page, then it recognized the changes.
I first have an insert statement something like this
$query = 'INSERT INTO matches (uid, win) VALUES ($uid, $win)';
mysql_query($query) or die(mysql_error() . ' in ' . $query);
Then, just after this, I have a select statement like
$query = "SELECT * FROM matches where uid = $uid";
$resultmain = mysql_query($query) or die(mysql_error() . ' in ' . $query);
Of course I simplified the queries but, that is the general idea - and what happens is: the select statement will not recognize the update that was run immediately before it. However, if I reload the page, and the select statement runs again after some time, it does recognize the change.
I googled for this and was very surprised to not come across anything yet. Is there any good way to force to wait until the mysql update query finished before selecting? If not, I might just have to use javascript to automatically reload the page, but this sounds like a messy solution.
Any help would be greatly appreciated, this has been driving me crazy...
--Anthony
That should not happen. Maybe it’s a problem in your code, which you did not post?
Things that come to mine, which could be the problem:
The 2 queries are run on different connections to the MySQL database. And auto-commit is not enabled.
Thus, first query would send the update but not commit, the second query will query on old data, and only after the page finishes (/later on) the commit occurs.
I’m not quite sure if non-auto-commited changes will be commited or rolled back when a PHP script ends, but it should be a rollback. Thus a later commit would be needed in your code as well for this possible scenario to apply.

Postgresql and PHP: is the currval a efficent way to retrieve the last row inserted id, in a multiuser application?

Im wondering if the way i use to retrieve the id of the last row inserted in a postgresql table is efficent..
It works, obviously, but referencing on the serial sequence currval value could be problematic when i have many users adding rows in the same table at the same time.
My actual way is:
$pgConnection = pg_connect('host=127.0.0.1 dbname=test user=myuser password=xxxxx')or die('cant connect');
$insert = pg_query("INSERT INTO customer (name) VALUES ('blabla')");
$last_id_query = pg_query("SELECT currval('customer_id_seq')");
$last_id_results = pg_fetch_assoc($last_id_query);
print_r($last_id_results);
pg_close($pgConnection);
Well, its just a test atm.
But anyway, i can see 3 issues with this way:
Referencing on the customer_id_seq, if two user do the same thing in the same time, could happen that them both get the same id from that way... or not?
I have to know the table's sequence name. Becose pg_get_serial_sequence dont works for me (im newbie on postgresql, probably is a configuration issue)
Any suggestion/better ways?
p.s: i can't use the PDO, becose seem lack a bit with the transaction savepoint; I wont use zend and, in the end, i'll prefer to use the php pg_* functions (maybe i'll build up my classes in the end)
EDIT:
#SpliFF(thet deleted his answer): this would works better?
$pgConnection = pg_connect('host=127.0.0.1 dbname=test user=myuser password=xxxxx')or die('cant connect');
pg_query("BEGIN");
$insert = pg_query("INSERT INTO customer (name) VALUES ('blabla')");
$last_id_query = pg_query("SELECT currval('customer_id_seq')");
$last_id_results = pg_fetch_assoc($last_id_query);
print_r($last_id_results);
//do somethings with the new customer id
pg_query("COMMIT");
pg_close($pgConnection);
If you use a newer version of PostgreSQL (> 8.1) you should use the RETURNING clause of INSERT (and UPDATE) command.
OTOH if you insist on using one of the sequence manipulation functions, please read the fine manual. A pointer: "Notice that because this is returning a session-local value, it gives a predictable answer whether or not other sessions have executed nextval since the current session did."
Insert and check curval(seq) inside one transaction. Before commiting transaction you'll see curval(seq) for your query and no matter who else inserted at the same time.
Don't remember the syntax exactly - read in manual (last used pgsql about 3 years ago), but in common it looks like this:
BEGIN TRANSACTION;
INSERT ...;
SELECT curval(seq);
COMMIT;
ex. minsert into log (desc,user_id) values ('drop her mind',6) returning id

Categories