I found myselfe lately in need of pagination therefore i dug up my old mysql_query script that have served its purpose. I tried to redone it so it fits for my current MySQL PDO class but one thing isnt right.
The problem is that to find out how many pages query will produce, i need to first conduct entire query without LIMIT'ation, than i have to conduct again the same query to be able to limit it, it feels like waste of resources and time, those queries are really long, take approx 20 different filters to do it, so i believe that i must be doing something wrong.
Is there a way to check using PDO how many rows are there in total in the same time as applying LIMIT into it?
For now this is what i have to do:
exec i.e. this query:
SELECT * FROM inventory WHERE
season = ?,
category = ?,
code = ?,
storage = ?,
price > ?,
price < ?,
purchase_date > ?,
purchase_date < ?,
index_date > ?,
index_date < ?,
product_class = ?
and than i got access to afected rows so i can exec it again and append LIMIT:
SELECT * FROM inventory WHERE
season = ?,
category = ?,
code = ?,
storage = ?,
price > ?,
price < ?,
purchase_date > ?,
purchase_date < ?,
index_date > ?,
index_date < ?,
product_class = ?
LIMIT {$BEGIN}, {$END}
Thank you in advance for all the help :)
Why wouldn't you store all the query's result into an array, and print only the 10 first, then [11-20]. (10 is the arbitrary number of results showed)
Something like
for($i = ($page - 1) * 10; $i <= ($page * 10); i++)
{
echo $result[i]['season'];
// other things
}
Related
When trying to insert this problem generates me. Use of the undefined constant SEQUENCE_ID_PROBLEMA - assumed SECUENCIA_ID_PROBLEMA
I do not know where the problem is, please help.
My Oracle sequence:
<code>
CREATE SEQUENCE INFORMACION.SECUENCIA_ID_PROBLEMA
START WITH 0
MAXVALUE 9999999999999999999999999999
MINVALUE 0
NOCYCLE
NOCACHE
NOORDER;
</code>
My code in PHP:
<code>
$sql = "INSERT INTO $tabla (ID_PROBLEMA, HORA_INICIO, PROBLEMA, CAUSA,
SOLUCION, HORA_FIN, ID_ASIGNACION) VALUES (?, ?, ?, ?, ?, ?, ?)";
$stmt = odbc_prepare($Conex, $sql);
$success = odbc_execute($stmt,[SECUENCIA_ID_PROBLEMA.nextval,$HORA_INICIO,$PROBLEMA, $CAUSA,SOLUCION,sysdate, $ID_ASIGNACION] );
</code>
PHP and SQL are entirely different languages and what you're getting is a PHP warning triggered by the PHP interpreter:
define('FOO', 3.1416);
echo FOO; // 3.1416
echo BAR; // Warning: Use of undefined constant BAR - assumed 'BAR' (this will throw an Error in a future version of PHP)
Your code tries to handle the sequence name as dynamic input. You cannot use prepared statements for that because the whole purpose of prepared statements is to prevent that from happening. If you really have to, you need to generate the basic SQL skeleton with plain string functions:
$table = 'PROBLEMA';
$sequence = 'SECUENCIA_ID_PROBLEMA';
$sql = "INSERT INTO $table (ID_PROBLEMA, HORA_INICIO, PROBLEMA, CAUSA,
SOLUCION, HORA_FIN, ID_ASIGNACION) VALUES ($sequence.nextval, ?, ?, ?, ?, ?, ?)";
INSERT INTO PROBLEMA (ID_PROBLEMA, HORA_INICIO, PROBLEMA, CAUSA,
SOLUCION, HORA_FIN, ID_ASIGNACION) VALUES (SECUENCIA_ID_PROBLEMA.nextval, ?, ?, ?, ?, ?, ?)
However, your code also tries to feed the dynamic bound variable with a fixed hard-coded text. I wonder if this extra complexity is intentional and necessary. Having different tables with the same exact column names is a potential code smell :)
In the end you can not use the sequence from php. What I did was create a trigger in the Oracle Data Bae so that it executes the sequence when insert a new row
<code>
CREATE SEQUENCE INFORMACION.SECUENCIA_ID_PROBLEMA
START WITH 0
MAXVALUE 9999999999999999999999999999
MINVALUE 0
NOCYCLE
NOCACHE
NOORDER;
CREATE TRIGGER problema_on_insert
BEFORE INSERT ON PROBLEMA
FOR EACH ROW
BEGIN
SELECT SECUENCIA_ID_PROBLEMA.nextval
INTO :new.ID_PROBLEMA
FROM dual;
END;
</code>
I have two datetime values on sql database and I want to subtract them and get the difference as a number of hours.
So far I have created three values. Deptime and ArrTime as datetime values and here are my questions.
1) What value shall the third table be? can it be number because I want to use it for statistics?
2) How can I subtract the Deptime and Arrtime and store the differnce in the FlightTime?
Thanks in advance
DATEDIFF can get you your hours.
SELECT DATEDIFF(HOUR, Deptime,Arrtime ) AS FlightTime FROM YourTable.
If you are using tSQL then you could use the DATEDIFF function. You can use this function with hours but if you want fractions of hours then you can use minutes and then convert back to hours.
fraction of hours
SELECT CAST(DATEDIFF(MINUTE, Deptime,Arrtime) AS DECIMAL(30,10))/60 AS FlightTime
FROM TableName
whole hours
SELECT CAST(DATEDIFF(HOUR, Deptime,Arrtime)) AS FlightTime
FROM TableName
Since it is a calculated field, I would just create a view with the DATEDIFF function for the calculated field.
PHP has its own DateInterval routines that might give you more flexibility (and portability) than doing it in SQL.
$datetime1 = new DateTime($DepDate);
$datetime2 = new DateTime($ArrDate);
$FlightTime = $interval->format('%h');
I'm looking at your progress and see a couple of red flags. Since you're accepting user input and inserting it into a database, you should at the very least be using prepared, parameterized insert statements.
$PiRepSubmissionSqlQuery = '
INSERT INTO Pireps (
PID, FLID, DEPID, ARRID,
FlightPlan, AircraftType, Fuel,
DepDate, ArrDate, FlightTime,
Remarks, Server
)
VALUES (
?, ?, ?, ?,
?, ?, ?,
?, ?, ?,
?, ?
)
';
// This is just an example - don't forget to check for errors
$sth = mysqli_prepare($mydb, $PiRepSubmissionSqlQuery);
mysqli_stmt_bind_param(
$sth,
'iiiisssssiss', // these should correspond to your SQL datatypes
$PID, $FLID, $DEPID, $ARRID,
$FlightPlan, $AircraftType, $Fuel,
$DepDate, $ArrDate, $FlightTime,
$Remarks, $Server
);
mysqli_stmt_execute($sth);
You should use mysql function TIMESTAMPDIFF to get difference between dates. So your query should look like this:
$PiRepSubmissionSqlQuery = "INSERT INTO Pireps (PID, FLID, DEPID, ARRID, FlightPlan, AircraftType ,Fuel ,DepDate ,ArrDate, FlightTime ,Remarks ,Server)
VALUES ('$PID', '$FLID', '$DEPID', '$ARRID','$FlightPlan' ,'$AircraftType' ,'$Fuel','$DepDate' ,'$ArrDate' ,TIMESTAMPDIFF(HOUR, ArrDate, DepDate), '$Remarks' ,'$Server')";
I need to read the date that a request was created from our website. When that request is created, the information corresponding to that request and its meta-request is inserted in the DAI_REQ.REQUEST and DAI_REQ.META_REQUEST tables, respectively. We also have a dev server and a public deployment server. The problem happens only on our deployment server for some reason..
Unfortunately, the INSERT query to insert the information of the meta-request in the DAI_REQ.META_REQUEST table does not work, but the SELECT query I do right after does (so in my eyes, this removes any connection problems with the database/table itself). I also use the same syntax as the INSERT query I do on the DAI_REQ.REQUEST, so I do not think it is a query syntax problem. I also tried manually inserting as line within sql-server and it works fine. Finally, I echo'ed the value of $this->userId that I use as a parameter for the INSERT query to see if it contained the right ID, and it does. I did the same for the return value of $this->db->query(...), and it does NOT return anything (on our deployment server only).
I also know that my way of retrieving the last inserted row in a table is not perfect, but this is not the problem at hand here and it will be changed later on.
Here is the actual code where the problem happens:
public function dbInsert(){
// The actual problematic query
$this->db->query("INSERT INTO DAI_REQ.META_REQUEST ".
"(DATE_RECU, DATE_TERMINEE, USER_ID, STATUS) ".
"VALUES(GETDATE(), '', ?, 'R');", array($this->userId));
// This works fine though
$mr_select = $this->db->query("SELECT TOP 1 ID FROM DAI_REQ.META_REQUEST WHERE USER_ID = ? ORDER BY ID DESC;",
array($this->userId));
$mr_result = $mr_select->result_array();
$mr_id = $mr_result[0]['ID'];
$sim = 'N/A';
if(isset($this->recurrenceType))
$sim = 'Recurrent';
$this->db->query("INSERT INTO DAI_REQ.REQUEST ".
"(USER_ID, ASSIGNED_DATE, REQUEST_END_DATE, MODEL, EXPERIMENT, VARIABLE, START_DATE, END_DATE, ".
"LON_FROM, LAT_FROM, LON_TO, LAT_TO, RESOLUTION, FORMAT, SIMULATION, STATUS, ".
"CANCELLED_YN, PROJECT, MR_ID, URL_ORIGIN, DATE_EMAIL) ".
"VALUES(?, GETDATE(), '', ?, 'N/A', 'N/A', ?, ?, ?, ?, ?, ?, ?, ?, ?, 'R', 0, 'N/A', ?, ?, ?);",
array($this->userId, $this->model, $this->startDate, $this->endDate,
$this->lonFrom, $this->latFrom, $this->lonTo, $this->latTo,
$this->resolution, $this->format, $sim, $mr_id, $this->url_origin, $this->date_email));
$r_select = $this->db->query("SELECT TOP 1 ID FROM DAI_REQ.REQUEST WHERE USER_ID = ? ORDER BY ID DESC;",
array($this->userId));
$r_result = $r_select->result_array();
$this->id = $r_result[0]['ID'];
}
The database that the deployment server is using isn't set up to auto increment the ID column. In Microsoft SQL Server, for the ID column, you can set the Identity to Yes and Identity Increment to whatever number you want the ID column to increment by.
I am inserting values into a database.
If the time the values were created is less than 24 hours then I insert like this,
$stmt = $con->prepare('
INSERT INTO taggedPlaces
(id, created_time, place_id, city, country, latitude, longitude, state, street, zip, name)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
');
foreach($graphObject['tagged_places']->data as $data) {
if (time() - strtotime($data->created_time) < 86400) {
$stmt->execute(array(
$data->id,
$data->created_time,
$data->place->id,
$data->place->location->city,
$data->place->location->country,
$data->place->location->latitude,
$data->place->location->longitude,
$data->place->location->state,
$data->place->location->street,
$data->place->location->zip,
$data->place->name
));
}
}
Everytime I return to the page it takes the same entries and continuously adds them to the database.
I would like to say something like
if $data->created_time == any created_time value in the DB then don't add this value,
as well as currently I am doing
if (time() - strtotime($data->created_time) < 86400)
to make sure it is not older then 24 hours.
How can I add this condition?
Option 1: (Recommeded)
Make id the primary key for your table, taggedPlaces:
ALTER TABLE taggedPlaces ADD PRIMARY KEY(id)
Then change your insert statement to use INSERT IGNORE which will skip duplicate inserts.
Option 2:
Make created_time a unique field in taggedPlaces:
ALTER TABLE taggedPlaces ADD UNIQUE(created_time);
Then, again, use INSERT IGNORE to skip duplicates.
Option 3: (Not recommeded, but will work)
Prior to running your insert, perform another query to check if $data->created_time is already in the table:
$check = $con->prepare('
SELECT id FROM taggedPlaces
WHERE created_time = ?
');
$check->execute(array($data->created_time));
if (count($check->fetchAll()) == 0) {
// No duplicates found. Proceed...
}
I am trying to insert data from feed into the database using Zend and also adding a column date_updated in table so that whenever the article in feed is updated the column also gets updated. But the problem is, the first article is being inserted earlier and thenafter the others. So, when I am trying to do a select of top 10 articles based on date_updated DESC, the article being inserted at last is getting on top and if i use ASC then the older ones are getting selected. Please suggest how do i proceed. The query I am writing is:
$sql = "INSERT INTO news_article
(original_article_id, headline,summary, keywords, link, section, topic, date_published, date_updated, content, source_id)
VALUES (?,?,?,?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE
original_article_id = ?,
headline = ?,
summary = ?,
keywords = ?,
link = ?,
section = ?,
topic = ?,
date_published = ?,
date_updated = ?,
content = ?,
source_id = ?";
$values = array(
"original_article_id"=>$id,
"headline"=>$item->title,
"summary"=>$summary,
"keywords"=>$keywords,
"link"=>$item->link,
"section"=>"property",
"topic"=>"property",
"date_published"=>$formattedPubDate,
"date_updated"=>$currentDate,
"content"=>$data,
"source_id"=>"3"
);
$result = $db->query(
$sql,
array_merge(array_values($values), array_values($values))
);
and thenafter i am using
SELECT * FROM news_article ORDER BY date_updated DESC LIMIT 10
use below query
SELECT * FROM news_article ORDER BY date_updated DESC LIMIT 0,10
After limit we need to pass offset and number of records to fetch.