Im trying to get the following to work within php:
<?php
$qry="CREATE TEMPORARY TABLE IF NOT EXISTS `coursesearch` AS (
SELECT `TREKKER_ID`, `TREKKER_COMPANY`, `TREKKER_FULLDISPLAYNAME`, `TREKKER_POSTCODE`,
`TREKKER_ACTIVE`, `TREKKER_SUBSCRIBOPN`, `tbl_trials`.*,
`EROUTE_RIDERID`, `EROUTE_FKID`, `EROUTE_EXPIRYDATE`
FROM `tbl_trekks`,
`tbl_trials`,
`tbl_scores`
WHERE `TREKKER_POSTCODE`" . $pcode .
" AND `tbl_trials`.`TRIALID` = `tbl_trekks`.`TREKKER_ID`";
if( $checkscores===true )
{
$qry.=" OR (`tbl_scores`.`EROUTE_RIDERID` = `tbl_trekks`.`TREKKER_ID`
AND `tbl_scores`.`EROUTE_FKID` <> 0)";
}
$qry.= "); SELECT * FROM `coursesearch`;";
if( !is_array($arr = $dbOb->DB_runQuery("slt", $qry )) ) { return 0; }
else {
print_r( $arr );
}
?>
Ive tested it directly in the phpMyAdmin console and this works (Obviously without the php specific code and tags) the result set is displayed in the temp table 'coursesearch'. However running the code in php gives this standard error message :
Error: DB Class: 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 'SELECT * FROM coursesearch' at line 14.
I understand from researching in google and the mysql site that temporary tables dissappear once the script finishes but surely i'm outputting the resultset before the script finishes. Ive tried using aliases and prefixing all fields with their respective tables names, also tried without backticks in PHP - but the problem persists on the same line,
near 'SELECT * FROM coursesearch' at line 14
Have i misunderstood what temporary tables can achieve here??
Either use PHP multi_query() in mysqli or separate these into two separate queries (run separately)
If that means adding such functionality to your $dbOb-> to run a DB_runMultiQuery (that you have to write) instead of calling $dbOb->DB_runQuery, then that is what you have to do.
PHP Manual page on Multi Query
Executes one or multiple queries which are concatenated by a
semicolon.
Related
I have a function that is designed to copy a product with all attributes with help of sql querys. My problem is to return new_product_id to php after completion.
If i run sql script in phpmyadmin all is working.
If i run sql script with php function all is working.
What i need help with is how to assign mysql-set-variable: #new_product_id from last query to php variable that I want to return.
----- sql query ------
CREATE TEMPORARY TABLE tmptable SELECT * FROM product WHERE id='19' AND site_id='1';
UPDATE tmptable SET id = 0,parent_id='19',status_id='1',name_internal=concat('NEW ',name_internal);
INSERT INTO product SELECT * FROM tmptable;
SET #new_product_id = LAST_INSERT_ID();
DROP TABLE tmptable;
CREATE TEMPORARY TABLE tmptable SELECT * FROM product_abcd WHERE product_id='19' AND site_id='1';
UPDATE tmptable SET product_id = #new_product_id,id=0;
INSERT INTO product_abcd SELECT * FROM tmptable;
DROP TABLE tmptable;
CREATE TEMPORARY TABLE tmptable SELECT * FROM product_efgh WHERE product_id='19' AND site_id='1';
UPDATE tmptable SET product_id = #new_product_id,id=0;
INSERT INTO product_efgh SELECT * FROM tmptable;
DROP TABLE tmptable;
(Here is more correct SQL insert statements)
SELECT #new_product_id AS new_product_id;
----- sql query ------
----- php function (not complete)------
This function is working making a new copy of product, code below is not complete but works so please only focus on multiquery part.
//return 0 for fail or new product_id (!=0) for success
public function copyProduct($data){
$res=0;
//if something, build sql-query as
$sql="sql from above";
//if we have a query to run
if(!empty($sql)){
//this is multi query, use correct function
if ($this->connect()->multi_query($sql) === TRUE) {
//loop it
while ($this->connect()->more_results()){
$result=$this->connect()->next_result();
}//while more results
}//if multiquery ok
return $res;
}//end function copy
----- php function (not complete)------
above code works, i get a nice copy of product with
result =0 for fail and
result 1 for success, (this works)
How i would like it to work is
result= 0 for fail and
result= new_product_id for success
so i can redirect user to the newly created product and therefore save user one click.
Results from query, same from phpmyadmin as from php (all good so far, no incorrect querys at this time)
Mysql returned empty results (no rows) (create temporary table)
1 row affected (update tmpt table)
1 row insert (insert into product)
mysql returned emtpy result (set $new_product_id)
mysql returened empty results (drop tmp table)
mysql returned empty result (create temporary table)
mysql x row affected (update tmp table)
mysql x row affected (insert into table)
mysql returned empty results (drop table tmptable)
mysql returned empty results (create temporary table)
.... N.....
last query "showing rows 0-0 ( 1 total) (select #new_product_id)
new_product_id=25
What have I tried?
I placed the select variable as my final query, i thought it was smart only check last query and assign variable there, but i failed due to php mysqli fetch_assoc is not possible on non object.
so next up was not so bright, i know i have 16 results from mysql and i only need the result from one of them, but anyway i places this inside multiquery
----- php function (not complete)------
This function is working making a new copy of product, NOT WORKING assigning new_product_id
//return 0 for fail or new product_id (!=0) for success
public function copyProduct($data){
$res=0;
//if something, build sql-query as
$sql="sql from above";
//if we have a query to run
if(!empty($sql)){
//this is multi query, use correct function
if ($this->connect()->multi_query($sql) === TRUE) {
//loop it
while ($this->connect()->more_results()){
//insert,update,drop will return false even if sql is ok, this would be sufficient for us now
if ($result = $this->connect()->store_result()) {
$row = $result->fetch_assoc();
if(isset($row["new_product_id"])){
//new return value of newly copied product
$res=$row["new_product_id"];
$result->free();
}
}
$result=$this->connect()->next_result();
}//while more results
}//if multiquery ok
return $res;
}//end function copy
----- php function (not complete)------
Checking other questions on stackoverflow recommended sending multiple normal querys, this seems like a bad solution when multi_query exists.
checking php library for multiquery did me no good, i cant understand how it works, as many others pointed out the documentation seems like a copy from another function.
Remember that multi_query() sends a clump of SQL queries to MySQL server but waits for the execution of only the first one. If you want to execute SQL using multi_query() and get only the result of the last query ignoring the previous ones then you need to perform a blocking loop and buffer the results into PHP array. Iterate over all results waiting for MySQL to process each query and once MySQL responds there are no more results you can keep the last fetched result.
For example, consider this function. It sends a bunch of concatenated SQL queries to the MySQL server and then waits for MySQL to process each query one by one. Every result is fetched into PHP array and the last available array is returned from the function.
function executeMultiQueryAndGetOnlyLastResult(mysqli $mysqli):array {
$mysqli->multi_query('
SELECT "a";
SELECT 2;
SELECT "val";
');
$values = [];
do {
$result = $mysqli->use_result();
if ($result) {
// process the results here
$values = $result->fetch_all();
$result->free();
}
} while ($mysqli->next_result()); // next_result will block and wait for next query to finish on MySQL server
$mysqli->store_result(); // Needed to fetch the error as exception
return $values;
}
Obviously it would be much easier to send each query separately to MySQL instead. multi_query() is very complicated and has very limited use. It can be useful if you have a number of SQL queries which you cannot execute separately via PHP, but most of the time you should be using prepared statements and send each query separately.
Another one bites the dust, I gave up and defined an array of sql querys from 0 to 14 and run it as mysqli->query() instead. Thank you all for comments and your time.
You could try using .multi_query() for all the queries in your operation except the last one, the SELECT that returns the id you want. Then run that SELECT as a single query.
This is a robust solution to your problem: #-variables belong to MySql connections and persist for the lifetimes of those connections.
And, it makes for clean and predictable operation of your software. When you need a result set returned to your program, use a single query.
I have two tables, Requests & Accounting_Fundscenter_Request
I'm creating a SQL query in PHP that updates
Request_ID from Accounting_Fundscenter_Request WHERE ID is max
to
the max Request_ID from Requests
So far I have gotten the max(Request_ID) rom Requests, but I don't know how to take that value in php & sql and update the other Request_ID to equal that value.
Also, I cannot use the syntax "max(id)" because the "max" function will not work in my first query and I don't know why.
Here's what I have so far:
/* GET MAX ID FROM REQUESTS */
$selectMaxID = 'SELECT Request_ID FROM Requests ORDER BY Request_ID DESC LIMIT 1';
$maxIdResult = mysqli_query($conn, $selectMaxID); //run query
if (mysqli_num_rows($maxIdResult) > 0) {
while($maxid = mysqli_fetch_assoc($maxIdResult)) {
echo "Max Request ID: " . $maxid["Request_ID"]. "<br>";
} //echo result of
}
$insertFundsCenterMaxId = "INSERT INTO `Accounting_Fundscenter_Request` (
`Request_ID`,
VALUES (
$maxid["Request_ID"],
)
WHERE MAX(`ID`);";
/* RUN THE QUERY */
$insertFundsCenterMaxId = mysqli_query($conn, $insertFundsCenterMaxId);
This does not work. Is there a way to fix this or maybe do it in one query?
EDIT: with your help I found the solution:
You have many options here:
You can fix the syntax error you have in you insert query execution like this:
$insertFundsCenterMaxIdQuery = sprintf('INSERT INTO Accounting_Fundscenter_Request (Request_ID) VALUES (%d)', $maxid["Request_ID"]);
/* RUN THE QUERY */
$insertFundsCenterMaxId = mysqli_query($conn, $insertFundsCenterMaxIdQuery);
This way you use string formatting to replace the variable instead of directly using $maxid["Request_ID"] in a string.
Please replace %d with %s in case the Request_ID is supposed to be string/varchar.
Or you can follow another approach and just use one query to do the work like this:
INSERT INTO Accounting_Fundscenter_Request (Request_ID)
SELECT MAX(Request_ID) FROM Requests
And just execute this query
You're facing a syntax error in the update query:
$insertFundsCenterMaxId = "INSERT INTO `Accounting_Fundscenter_Request` (
`Request_ID`,
VALUES (
$maxid["Request_ID"],
)
WHERE MAX(`ID`);";
Using the double quotes in that variable hiding in the VALUES part, you are ending the string contained in insertFundsCenterMaxId. Following it is a raw string containing Request_ID which cannot be parsed by PHP. That's simply invalid code.
To solve it, you could start using prepared statements. They will also help you to secure your application against SQL injection.
There is also a solution to the syntax error problem alone - but that will leave your application vulnerable. That's why I haven't included a fix for that, but by checking how to build strings you might find it on your own. But please, please do not use it for this problem. Please.
I have the following simple query which works perfectly in MySQL;
select * from client_contact
where date_format(client_next_contact_on, '%Y-%m-%d') = '2018-07-25'
I've then added this in my codeigniter query but the error I get is;
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 ''2018-07-25'' at line 3
SELECT * FROM (client_contact) WHERE
dateformat(client_next_contact_on, '%Y-%m-%d') '2018-07-25'
By the looks of the above, it's missing the = in the query.
Here's my query in codeigniter;
$today = new DateTime();
$today_formatted = $today->format('Y-m-d');
$this->db->where('dateformat(client_next_contact_on, \'%Y-%m-%d\')', $today_formatted);
$return = $this->db->get('client_contact')->row_array();
If you're wondering why I need to use date_format, it's because it's stored as a date time in my database for other purposes. For this purpose, I need a list of clients that I need to contact today, regardless of the time.
Just include the equals in the where statement, and rename dateformat as it isn't a function in MySQL. Use DATE_FORMAT:
$this->db->where('DATE_FORMAT(client_next_contact_on, \'%Y-%m-%d\') =', $today_formatted);
Now, onto the guts of why code igniter chose not to include an equals sign, which (by the documentation, it should have). On this line of the codeigniter source, it calls this function to determine if it contains an operator. Apparently because you put a space after the , it believed you included an operator, so a simple manual adjustment to add this in is fine.
protected function _has_operator($str)
{
return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str));
}
You can see where the regex matched here: https://regex101.com/r/BTuZxj/1
I would like to combine two columns in one column as Fullname, and for that I have written the following code:
$this->db->select('CONCAT(first_name," ",last_name) AS FullName');
$this->db->from('customer');
$this->db->where('user_id',1);
$query = $this->db->get();
return $query->result_array();
The resulting query would be:
SELECT CONCAT(first_name," ",last_name) AS FullName
FROM customer
WHERE user_id = 1
but when i execute the above code it gives me:
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 'FROM (customer) WHERE user_id = '1' at line 2
I have also tried with concat_ws group_concat but not able to get it work. Can anyone see what I'm doing wrong?
By default, CI tries to escape what you pass to db->select() (in case you were passing in user-generated values). You can disable this feature by passing false as a second argument.
$this->db->select('CONCAT(first_name," ",last_name) AS FullName', false);
I have been through this before with CI, in my case CI was wrongly creating the query, for example putting simgle quotes where they shouldn't be.
My advice create the query yourself and run it, you could be surprise :P
A PHP application on the server is saving a certain document with a sequential number into a MySQL database. How to obtaion that sequential number to a command line prompt that initiates the local doocument scanner?
ex:
c:\myscan ask_for_current_seq_nmbr.pdf
myscan is something written in c that takes care of the PC stuff. Only the name of file is unknown.
Some code (from the query PHP file)
$query = "SELECT last_seq FROM seq_table WHERE cat = 1";
$result = mysql_query($query, $link) or die('ERROR: '. mysql_error().'<br />ON LINE: '.__LINE__);
while($row = mysql_fetch_assoc($result)) {
echo $row['last_seq'];
}
!!! NOTE !!!
I am fetching a page from a remote server. ex. www.site.com/query.php?q=SELECT * FROM...
And that selection results in the last used sequential number which I would like to use in my command prompt.
!! UPDATE !!
We HAVE to go through a PHP file on the remote server to avoid having to use Remoote MySQL which has to be enabled on an IP basis.
You can call processes that run on the commandline with various function from PHP from the exec familyDocs.
If you're having problems building the actual command string, you can do with:
$cmd = sprintf('c:\myscan %d.pdf', $sequential_number);
As you write that the script is already writing it into the db with the $sequential_number I assume you have it already.
In case the database generates the number, then probably as the primary key. See mysql_insert_idDocs for obtaining the id.
Okay judging by the backslash and the C:\ I am guess you're using windows.
You are going to have to combine the following:
http://dev.mysql.com/doc/refman/5.5/en/mysql.html
How to store the result of a command expression in a variable using bat scripts?
and then to access the content of the variable you created use the %VARIABLE_NAME% syntax.
You should have flag in your mysql table like is_processed with value = 0 or 1.
When scan starts it runs query:
SELECT * FROM TABLE where is_processed = 0 order by sec_number
After processing you should run query:
UPDATE TABLE set is_processed = 1 where sec_number = 'sec_processed_number';