I am using prepared statements for a search functionality using PDO and I am using the like clause. Mysql is 5.5.32
function dblink(){
# hidden #
$conn = new PDO("mysql:host=localhost;dbname=$database",
$username, $password, array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ
));
return $conn;
}
$conn = dblink();
$query = "select * from tablename where attrib like ? ;";
$stmt = $conn->prepare($query);
$stmt->execute(array($_POST['field']."%"));
$results = $stmt->fetchAll(PDO::FETCH_OBJ);
This dumps all the table contents when user enters % for field in the html form. I thought prepared statement would handle it and there is % in execute so that it matches the substring entered.
How do I use the POST field as normal text only so that it doesn't cause such problem?
This dumps all the table contents when user enters % for field in the html form.
Yes. That's the exact purpose of LIKE operator.
No, it has nothing to do with prepared statement. The latter is used to format your data, not to interfere with query logic.
If you don't like the way your code works - change it. But at the moment it works exactly the way you coded, with no flaws.
Related
I am trying to diedump the query on my index screen using this line of code:
dd(DB::table('members')->where('name', '=', 'Tycho')->toSql());
Now the problem is that when I am displaying the query on my screen I get this:
"select * from `members` where `name` = ?"
My final goal of these lines of code is that I can save offline queries and execute them when the application is online. Unless someone has a solution for this, I'll have to save the queries in a database.
You are seeing the ? placeholders as Laravel uses Prepared Statements.
See Ijas Ameenudeen's answer on another SO question which details how to add a toRawSql() macro on the Eloquent builder which will replace the placeholders with the bindings that you supplied to the original query.
This is because you are using the toSql method, you can use the getBindings method to get the values / bindings.
oneliner:
$query = DB::table('members')->where('name', '=', 'Tycho')->toSql();
// will give the raw query with bindings.
$sqlWithBindings = str_replace_array('?', $query->getBindings(), $query->toSql());
You can try this:
DB::enableQueryLog();
DB::table('members')->where('name', '=', 'Tycho')->get();
echo "<pre>";
print_r(DB::getQueryLog());
I am using the following code to load a categorys record:
$res = JTable::getInstance('category');
$res->load(array('id' => $catid));
Now I would like to load the record based on its title which whould be matched against a SQL LIKE-pattern - is it possible to do this in a simple way with JTable, or do I need $dbo?
Far as I know JTable is made to be simple and carry only one element at a time, and through the primary key. If you really want something more advanced, I recomend that you use JDatabaseQuery way.
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all articles for users who have a username which starts with 'a'.
// Order it by the created date.
$query
->select(array('a.*', 'b.username', 'b.name'))
->from('#__content AS a')
->join('INNER', '#__users AS b ON (a.created_by = b.id)')
->where('b.username LIKE \'a%\'')
->order('a.created DESC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects.
$results = $db->loadObjectList();
In your case, instead of "$db->loadObjectList();" you can use "$db->loadObject();" for load just one item.
Source:
http://docs.joomla.org/Accessing_the_database_using_JDatabase/3.1
I want to query a table and only need one cell returned. Right now the only way I can think to do it is:
$query = $this->db->query('SELECT id FROM crops WHERE name = "wheat"');
if ($query->num_rows() > 0) {
$row = $query->row();
$crop_id = $row->id;
}
What I want is, since I'm select 'id' anyway, for that to be the result. IE: $query = 'cropId'.
Any ideas? Is this even possible?
Of course it's possible. Just use AND in your query:
$query = $this->db->query('SELECT id FROM crops WHERE name = "wheat" AND id = {$cropId}');
Or you could use the raw power of the provided Active Record class:
$this->db->select('id');
$this->db->from('crops');
$this->db->where('name','wheat');
$this->db->where('id',$cropId);
$query = $this->db->get();
If you just want the cropId from the whole column:
foreach ($query->result()->id as $cropId)
{
echo $cropId;
}
Try this out, I'm not sure if it will work:
$cropId = $query->first_row()->id;
Note that you want to swap your quotes around: use " for your PHP strings, and ' for your SQL strings. First of all, it would not be compatible with PostgreSQL and other database systems that check such things.
Otherwise, as Christopher told you, you can test the crop identifier in your query. Only if you define a string between '...' in PHP, the variables are not going to be replaced in the strings. So he showed the wrong PHP code.
"SELECT ... $somevar ..."
will work better.
Yet, there is a security issue in writing such strings: it is very dangerous because $somevar could represent some additional SQL and completely transform your SELECT in something that you do not even want to think about. Therefore, the Active Record as mentioned by Christopher is a lot safer.
I'm working on an application using ZF2. In my application, I have to insert many rows in a database (about 900).
I've got a table model for this, so I first try to do :
$table->insert(array('x' => $x, 'y' => $y));
in my loop. This technically work, but this is so slow that I can hardly insert half of the datas before php's timeout (and I can't change the timeout).
Then, I've decide to use a prepared statment. So I've prepared it outside of the loop, then execute it in my loop... it was even slower.
So, I decide to stop using ZF2 tools, as they seems to be too slow to be used in my case, and i've created my own request. I'm using mysql, so i can do a single request with all my values. But I can't find any method in any of the interface to escape my values...
Is there any way to do this ?
Thank you for your help and sorry for my poor english.
If you want to perform raw queries you can do so using the Database Adapter:
$sql = 'SELECT * FROM '
. $adapter->platform->quoteIdentifier('users')
. ' WHERE ' . $adapter->platform->quoteIdentifier('id') . ' = ' . $adapter->driver->formatParameterName('id');
/* #var $statement \Zend\Db\Adapter\Driver\StatementInterface */
$statement = $adapter->query($sql);
$parameters = array('id' => 99);
/* #var $results Zend\Db\ResultSet\ResultSet */
$results = $statement->execute($parameters);
$row = $results->current();
use transactions: http://dev.mysql.com/doc/refman/5.0/en/commit.html
Than will help you to decrease the execution time
I have some extremely complex queries that I need to use to generate a report in my application. I'm using symfony as my framework and doctrine as my ORM.
My question is this:
What is the best way to pass in highly-complex sql queries directly to Doctrine without converting them to the Doctrine Query Language? I've been reading about the Raw_SQL extension but it appears that you still need to pass the query in sections (like from()). Is there anything for just dumping in a bunch of raw sql commands?
$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$result = $q->execute(" -- RAW SQL HERE -- ");
See the Doctrine API documentation for different execution methods.
Yes. You can get a database handle from Doctrine using the following code:
$pdo = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
and then execute your SQL as follows:
$query = "SELECT * FROM table WHERE param1 = :param1 AND param2 = :param2";
$stmt = $pdo->prepare($query);
$params = array(
"param1" => "value1",
"param2" => "value2"
);
$stmt->execute($params);
$results = $stmt->fetchAll();
You can use bound variables as in the above example.
Note that Doctrine won't automatically hydrate your results nicely into record objects etc, so you'll need to deal with the results being returned as an array, consisting of one array per row returned (key-value as column-value).
I'm not sure what do you mean saying raw SQL, but you coud execute traditional SQL queries this way:
...
// $this->_displayPortabilityWarning();
$conn = Doctrine_Manager::connection();
$pdo = $conn->execute($sql);
$pdo->setFetchMode(Doctrine_Core::FETCH_ASSOC);
$result = $pdo->fetchAll();
...
The following method is not necsessary, but it shows a good practice.
protected function _displayPortabilityWarning($engine = 'pgsql')
{
$conn = Doctrine_Manager::connection();
$driver = $conn->getDriverName();
if (strtolower($engine) != strtolower($driver)) {
trigger_error('Here we have possible database portability issue. This code was tested on ' . $engine . ' but you are trying to run it on ' . $driver, E_USER_NOTICE);
}
}
You can also use Doctrine_RawSql(); to create raw SQL queries which will hydrate to doctrine objects.
It should be noted, that Doctrine2 uses PDO as a base, thus I would recommend using prepared statements over plain old execute.
Example:
$db = Doctrine_Manager::getInstance()->getCurrentConnection();
$query = $db->prepare("SELECT `someField` FROM `someTable` WHERE `field` = :value");
$query->execute(array('value' => 'someValue'));
Symfony insert raw sql using doctrine.
This in version Symfoney 1.3
$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$result = $q->execute($query);