Equal in select does not work as expected - pdo

I found a funny behaviour using equal with pdo. I checked several select-statements in phpmyadmin and pdo and the results vary. Has someone a idea whats wrong?
$sql = "select * from fenster where fenster > 'news'"; //works ok
$sql = "select * from fenster where fenster < 'news'"; //works ok
$sql = "select * from fenster where fenster <= 'news'"; //works ok
$sql = "select * from fenster where fenster >= 'news'"; // news is not in result
$sql = "select * from fenster where fenster = 'news'"; // news is not in result
$stmt = $db->prepare($sql);
$stmt->execute();
$feldName = array_keys($stmt->fetch(PDO::FETCH_ASSOC));
while($data = $stmt->fetch()) {
var_dump($data);
}

I found the reason myself.
The $feldName = array_keys($stmt->fetch(PDO::FETCH_ASSOC)); did read the missing row, so it did not show afterwards. So I have to find a workaround.

Related

Query with doctrine 1

I try to make the following sql query from phpMyAdmin who works perfectly and return 1 result with doctrine 1 but i get an exception :
SQLSTATE[42S22]: Column not found: 1054 Champ 'MOY1100' inconnu dans
where clause. Failing Query: "select id_au FROM acteur_unite WHERE
code_unite = MOY1100 LIMIT 1"
Here the sql query who work on phpMyAdmin :
SELECT id_au FROM acteur_unite WHERE code_unite = 'MOY1100' LIMIT 1
Here my query with doctrine :
public function getId($code_unite) {
$con = Doctrine_Manager::getInstance()->connection();
$st = $con->execute("select id_au FROM acteur_unite
WHERE code_unite = $code_unite LIMIT 1");
$id = null;
// fetch query result
$data = $st->fetch(PDO::FETCH_ASSOC);
$id = $data['id_au'];
return $id;
}
Where i'm wrong ?
Thanks a lot in advance
seems you missing the quote around var $code_unite
$st = $con->execute("select id_au FROM acteur_unite
WHERE code_unite = '$code_unite' LIMIT 1");
but be careful with the use of var in sql .. you are at risk for sql injection . Then check for your framework the right way for the param_binding .. for avoid this risk
eg:
$st = $con->execute("select id_au FROM acteur_unite
WHERE code_unite = :code_unite LIMIT 1");
$st->bindParam(':code_unite', $code_unite, PDO::PARAM_STR);

PDO and prepared statements

I'm trying to implement this query:
SELECT AVG(timediff(end, start)) AS avg_in FROM phone_call
WHERE user_id=2
AND direction = 'o'
AND DATE(start) = DATE('2013-11-04 17:11:37')
using PDO with PHP. Could you provide some advice on how to do this. Ive tried:
$uid = 2; $direction='o'; $date='2013-11-04 17:11:37';
$q = "SELECT AVG(timediff(end, start)) AS avg_in FROM phone_call
WHERE user_id = ?
AND direction = ?
AND DATE(start) = DATE(?))";
$stmt = $this->pdo->prepare($q);
$stmt->bindParam(1, $uid, PDO::PARAM_INT, 5);
$stmt->bindParam(2, $direction, PDO::PARAM_STR, 1);
$stmt->bindParam(3, $date, PDO::PARAM_STR, 20);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
//$result = round($result,2);
return $result;
but this fails.
edit:
client code:
$a = $call_log->getAvCallIn(2,'o','2013-11-04 17:11:37'); //
print '<pre>';print_r($a);
nothing get printed to the screen!
I suspect it's the
AND DATE(start) = DATE(?))
part of the query that is faulty?

SELECT issue moving from PG_query to PDO

I have a select statement see below. Using PDO how would I recreate this same Select statement, as I want to grab two values from it and combine them into the $geomstring. I can figure out the combine, but not the first 3 lines.
$sql1 = "SELECT easting_value, northing_value FROM gridreference_tbl WHERE gridref_id='$_POST[gridref_id]'";
$result1 = pg_query($sql1);
$row1 = pg_fetch_array($result1);
$geomstring = $row1['easting_value']. $_POST['grid_eastings']." ".$row1['northing_value'].$_POST['grid_northings'];
*php website for prepared statements says *
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name']))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
I have something similar working for populating a dropdown that partly uses this
$stmt = $conn->prepare("SELECT easting_value, northing_value FROM gridreference_tbl WHERE gridref_id=$gridref_id");
$stmt->setFetchMode(PDO::FETCH_OBJ);
Found it on php.net, I was googling the wrong stuff:
$stmt4 = $conn->prepare("SELECT easting_value, northing_value from gridreference_tbl WHERE gridref_id = 4");
$stmt4->execute();
print("PDO::FETCH_ASSOC: ");
print("Return next row as an array indexed by column name\n");
$result = $stmt4->fetch(PDO::FETCH_ASSOC);
print_r($result);
print("\n");

Data retrieval from database using perl with a foreach

$dbh_source2 = DBI->connect("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
foreach $data_line (#raw_data) {
$SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = '$data_line'";
$sth = $dbh_source2->prepare($SEL);
$sth->execute();
while (my #row = $sth->fetchrow_array() ) {
print #row;
print "\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}
I am trying to grab several lines of data from a user. I want to take that data and use it to query a database and grab ARG1 and ARG2 WHERE USER_DATA = $data_line.
It will not display anything.
Here's a quick revision which uses SQL placeholders in order to keep Bobby Tables from destroying your database. It may also fix the problem you're currently having, but I haven't seen enough details of your problem yet to be sure.
my $dbh_source2 = DBI->connect("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
my $SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = ?";
my $sth = $dbh_source2->prepare($SEL);
foreach my $data_line (#raw_data) {
$sth->execute($data_line);
while (my #row = $sth->fetchrow_array() ) {
print #row;
print "\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}
my $dbh_source2 = DBI->connect
("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
my $SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = ?";
my $sth = $dbh_source2->prepare($SEL);
foreach my $data_line (#raw_data) {
chomp $data_line;
$sth->execute($data_line);
while (my #row = $sth->fetchrow_array() ) {
print "$data_line\t #row\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}
The issue I was having was the fact that the development database was not updated with the correct information so some of the items came up blank. When using the production database with the correct information it worked great!
Thank you all for your help!

Is this SQL code concurrent safe?

I am pretty sure this code is fine. I wanted to know what you guys think about the insertMediaTags function (2nd func). The things i am worried about is the below concurrent safe? and if insertMediaTags is optimize enough? note it is in a transaction due to first func but it is also in a loop which could mean its bad?
I am open to any coding practice, style or suggestions you guys may have.
(I know someone will ask, i am using sqlite ATM but its prototype code to use with mysql or a version of ms sql or another)
{
long mediaId;
//all the credentials should be verified by this point.
command.CommandText = "SELECT mediaId FROM media " +
"WHERE userId=#userId AND title=#title;";
command.Parameters.Add("#userId", DbType.Int64).Value = m.userid;
command.Parameters.Add("#title", DbType.String).Value = m.title;
if (command.ExecuteScalar() != null)
throw new System.InvalidOperationException("Title already exisit");
using (var dbTrans = connection.BeginTransaction())
{
command.CommandText =
"INSERT INTO " +
"media ( userid, catagory, creation_date, current_media_date, current_desc_date, licence, title, desc, ext) " +
"VALUES(#userid, #catagory, #creation_date, #current_media_date, #current_desc_date, #licence, #title, #desc, #ext); " +
"SELECT last_insert_rowid() AS RecordID;";
DateTime currentDate = m.creation_date;
command.Parameters.Add("#userid", DbType.Int64).Value = m.userid;
command.Parameters.Add("#catagory", DbType.Int64).Value = m.catagory;
command.Parameters.Add("#creation_date", DbType.DateTime).Value = m.creation_date;
command.Parameters.Add("#current_media_date", DbType.DateTime).Value = currentDate;
command.Parameters.Add("#current_desc_date", DbType.DateTime).Value = currentDate;
command.Parameters.Add("#licence", DbType.Int64).Value = m.license;
command.Parameters.Add("#title", DbType.String).Value = m.title;
command.Parameters.Add("#desc", DbType.String).Value = m.desc;
command.Parameters.Add("#ext", DbType.Int64).Value = m.ext;
mediaId = (long)command.ExecuteScalar();
//m.collaborateWith
insertInspired(inspireLinks.external, inspireLinks.internalPair, mediaId);
insertDerived(deriveLinks.external, deriveLinks.internalPair, mediaId);
insertMediaTags(m.listTagString, mediaId);
//command.CommandText = "END TRANSACTION;"; command.ExecuteNonQuery();
updateMediaForWatchers(m.userid, mediaId, m.catagory, currentDate);
dbTrans.Commit();
}
return mediaId;
}
void insertMediaTags(List<string> tags, long mediaId)
{
foreach(string tag in tags)
{
//assure tag exist
long tagId;
command.CommandText = "SELECT tagid FROM tag_name WHERE title=#title;";
command.Parameters.Add("#title", DbType.String).Value = tag;
object o = command.ExecuteScalar();
if (o == null)
{
command.CommandText =
"INSERT INTO tag_name(title) VALUES(#title); " +
"SELECT last_insert_rowid() AS RecordID;";
command.Parameters.Add("#title", DbType.String).Value = tag;
tagId = (long)command.ExecuteScalar();
}
else
tagId = (long)o;
command.CommandText =
"INSERT INTO media_tags(mediaId, tagid) " +
"VALUES(#mediaId, #tagid);";
command.Parameters.Add("#mediaId", DbType.Int64).Value = mediaId;
command.Parameters.Add("#tagid", DbType.Int64).Value = tagId;
command.ExecuteNonQuery();
command.CommandText =
"UPDATE tag_name SET count = count+1 "+
"WHERE tagid=#tagid";
command.Parameters.Add("#tagid", DbType.Int64).Value = tagId;
command.ExecuteNonQuery();
}
}
No it's not concurrent safe. You have a potential race condition between the SELECT to determine whether the tag exists, and the INSERT to create the tag if it does not. Imagine thread A does a SELECT and finds it does not exist, and then thread B does the same before thread A does the INSERT. Thread B will attempt the insert as well and fail.
In SQL Server, it's better to use the SCOPE_IDENTITY() function. Other than that I don't see a problem.