I'm getting following error when executing query .
Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''0', '25'' at line 1
here is the query
$sqlData = 'SELECT * FROM users WHERE u_id_id = :UID_ID ORDER BY :ORDER_BY :ORDER_TYPE limit :START, :DATA_LENGTH';
$params = array(
":UID" => $uId,
":ORDER_BY" => $orderBy,
":ORDER_TYPE" => $orderType,
":START" => $start,
":DATA_LENGTH" => $length
);
$queryData = \registry::getDBHandler()->prepare($sqlData);
$queryData->execute($params);
var_dump($queryData->execute($params));
note
here is the var dum output of paramas
array (size=5)
':UID' => string '66' (length=2)
':ORDER_BY' => string 'id' (length=2)
':ORDER_TYPE' => string 'asc' (length=3)
':START' => string '0' (length=1)
':DATA_LENGTH' => string '25' (length=2)
Prepared statements let you bind variables to the WHERE (and I think SELECT) clauses of an SQL query. Unfortunately, they do not let you bind to the ORDER BY or LIMIT (or FROM) clauses. For that, you will need to manually append to the string.
Since those values are not being entered by the user, you should be safe from SQL injection if you just do:
$sqlData = "SELECT * FROM users WHERE u_id_id = :UID_ID ORDER BY $orderBy $orderType LIMIT $start, $length";
(Note the double quotes around the string)
And then your $params array would just be:
$params = array(":UID" => $uId);
If you are worried about SQL injection, then you can use the following to help with that:
For your ORDER BY, you can make sure that your $orderBy is in a hard-coded list of fields and reject it if it is not.
For $orderType, just simply ensure it is equal to either "asc" or "desc" (possibly ignoring case).
With $start and $length, make sure they are integers. You can also try to use intval() to convert them if need be.
If you follow these rules, then it should be safe to append these variables into your SQL query. Since $uId is part of the WHERE, you can use the prepared variable for it and that is fine.
Related
I would like to find out the number of affected (inserted) rows after inserting into the table. I didn't figure out how to do it in the documentation. The update returns the number of affected rows. The insert returns Nette\Database\Table\ActiveRow
How do I get it?
$affected = $context->table('author')->insert([
[
'name' => 'Sansa Stark',
'born' => null
], [
'name' => 'Arya Stark',
'born' => null
]
]);
bdump($affected); // Nette\Database\Table\ActiveRow - I need the number of inserted records
Nette Database Explorer doesn't return count after insert(). It is not useful information as long as you can count data before insert by yourself.
$data = [...];
$count = count($data);
$context->table('author')->insert($data);
It works only with update and delete as is mentioned in documentation.
$count = $context->table('author')
->where('id', 10)
->delete();
It might be possible with getRowCount() over query in Nette Database Core
Nette Database Core is built upon PDO. Alas, the authors tend to create their own objects instead of extending PDO, which makes such elementary operations tedious:
// get Nette ResultSet object
$resultSet = $this->database->query("INSERT/UPDATE/DELETE...");
// get original PDOStatement object
$pdoStatement = $resultSet->getPdoStatement();
// get the affected rows from PDO object (instead of $resultSet->rowCount())
$pdoStatement->rowCount();
A word of warning for those considering Nette for production: There is no real documentation, only cook books and autogenerated PHPDoc which just prints names without any explanation.
I am using Omines Symfony DataTable Bundle https://omines.github.io/datatables-bundle/#doctrine-orm to organize my event table.
I am unable to search on my "Début" and "Fin" columns which are of type Datetime Column. I'm guessing because since these are DateTime objects I'm guessing it can't find a match.
mytable
If I type "08/19/2020" it doesn't find any results for me.
Here: https://datatables.net/forums/discussion/44218/how-do-i-search-on-a-datetime-column it advises to format the date on the server side, so I tried that (of course j 've installed the doctrine extensions to be able to use date_format):
->createAdapter(ORMAdapter::class, [
'entity' => Event::class,
'query' => function (QueryBuilder $builder) use ($eventStatus) {
$builder
->select('e')
->addSelect('DATE_FORMAT(e.startDate, "%d/%m/%Y")')
->addSelect('ca')
->addSelect('ci')
->addSelect('u')
->from(Event::class, 'e')
->join('e.category', 'ca')
->join('e.city', 'ci')
->join('e.user', 'u')
->andWhere('e.status = :status')
->setParameter('status', $eventStatus)
->orderBy('e.id', 'DESC')
;
},
])
I also changed my dateStart column to TextColumn:
->add('startDate', TextColumn::class, ['label' => 'Début', 'field' => 'e.startDate', 'render' => function($value, $context) {
return sprintf(
'%s<br>
%s',
$value,
$context->getStartAt()->format('H\hi'),
);
}])
And I have this error:
Uncaught PHP Exception Doctrine \ ORM \ Query \ QueryException: "[Syntax Error] line 0, col 34: Error: Expected StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression, got '"' "
I do not see where the problem is.
Thanks for your help.
It's difficult to tell from the question you are asking, but there are certain things that look problematic in your code.
First, you use a custom query, but you don't use any WHERE clause with the date.
Second, your formatting of the column is not named. The result can't be accessed since it doesn't have a name. You can name it with the keyword AS:
->addSelect('DATE_FORMAT(e.startDate, "%d/%m/%Y") AS startDateFormatted')
Third, you use joins and then you shouldn't use ORMAdapter but FetchJoinORMAdapter (this will help you solve problems with pagination when using joins).
In my opinion, you shouldn't try to format the startDate in the query, but check the documentation and use a Criteria
https://omines.github.io/datatables-bundle/#doctrine-orm
I use JetPack stats to follow the stats for my blog. I would like to extract the top 10 most-viewed posts for a given period (e.g. last month).
I used the WordPress stats plugin API before which worked nicely, but after upgrade to JetPack this doesn't work anymore.
Is there an API which allows me to query the number of view counts for a post?
Inside the Database
This option is recorded in the database and is used by the Dashboard widget:
get_option( 'stats_cache' );
It returns an array like this:
array(
['7375996b7a989f95a6ed03ca7c899b1f'] => array(
[1353440532] => array(
[0] => array(
['post_id'] => 0
['post_title'] => 'Home page'
['post_permalink'] => 'http://www.example.com/'
['views'] => 1132
)
[1] => array(
['post_id'] => 4784
['post_title'] => 'Hello World!'
['post_permalink'] =>
['views'] => 493
)
/* till item [9] */
Querying WordPress.com
It is possible to call the following Jetpack function:
if( function_exists( 'stats_get_csv' ) ) {
$top_posts = stats_get_csv( 'postviews', 'period=month&limit=30' );
}
Which returns:
array(
[0] => array(
['post_id'] => 0
['post_title'] => 'Home page'
['post_permalink'] => 'http://www.example.com/'
['views'] => 6806
)
[1] => array(
['post_id'] => 8005
['post_title'] => 'Hello World!'
['post_permalink'] =>
['views'] => 1845
)
/* till item [29] */
Function get_stats_csv
/plugins/jetpack/modules/stats.php
The function get_stats_csv calls http://stats.wordpress.com/csv.php. If we visit this address, we get this response:
Error: api_key is a required parameter.
Required parameters: api_key, blog_id or blog_uri.
Optional parameters: table, post_id, end, days, limit, summarize.
Parameters:
api_key String A secret unique to your WordPress.com user account.
blog_id Integer The number that identifies your blog.
Find it in other stats URLs.
blog_uri String The full URL to the root directory of your blog.
Including the full path.
table String One of views, postviews, referrers, referrers_grouped,
searchterms, clicks, videoplays.
post_id Integer For use with postviews table.
end String The last day of the desired time frame.
Format is 'Y-m-d' (e.g. 2007-05-01)
and default is UTC date.
days Integer The length of the desired time frame.
Default is 30. "-1" means unlimited.
period String For use with views table and the 'days' parameter.
The desired time period grouping. 'week' or 'month'
Use 'days' as the number of results to return
(e.g. '&period=week&days=12' to return 12 weeks)
limit Integer The maximum number of records to return.
Default is 100. "-1" means unlimited.
If days is -1, limit is capped at 500.
summarize Flag If present, summarizes all matching records.
format String The format the data is returned in,
'csv', 'xml' or 'json'.
Default is 'csv'.
Non-working query example:
?api_key=123456789abc&blog_id=155&table=referrers&days=30&limit=-1&summarize
Result format is csv with one row per line and column names in first row.
Strings containing double quotes, commas, or "\n" are enclosed in double-quotes.
Double-qoutes in strings are escaped by inserting another double-quote.
Example: "pet food" recipe
Becomes: """pet food"" recipe"
Developers, please cache the results for at least 180 seconds.
The symfony framework features an app/console file that can be executed via php to perform some maintenance tasks. It allows users to run DQL queries as well:
# php app/console doctrine:query:dql --hydrate=array \
'SELECT u.id, u.nameFirst, u.nameLast FROM DatabaseBundle:User u'
array
0 =>
array
'id' => string '1' (length=1)
'nameFirst' => string 'jaroslav' (length=8)
'nameLast' => string 'rakhmatoullin' (length=13)
1 =>
array
'id' => string '2' (length=1)
'nameFirst' => string 'Båb Kåre' (length=10)
'nameLast' => string 'Ytrefoss' (length=8)
Observe that I selected three specific columns. The problem I'm having is that a similar query gives me an error when two tables are joined.
# php app/console doctrine:query:dql --hydrate=array \
'SELECT u.id , r FROM DatabaseBundle:User u JOIN u.roles r'
[Doctrine\ORM\Query\QueryException]
[Semantical Error] line 0, col -1 near 'SELECT u.id ,':
Error: Cannot select entity through identification variables
without choosing at least one root entity alias.
The following returns the whole user joined with his roles:
# php app/console doctrine:query:dql --hydrate=array \
'SELECT u, r FROM DatabaseBundle:User u JOIN u.roles r'
Obviously, I'm missing something.
Any ideas? I would appreciate links to appropriate docs too (on this specific matter).
From the documentation on "Partial Object Syntax":
By default when you run a DQL query in Doctrine and select only a subset of the fields for a given entity, you do not receive objects back. Instead, you receive only arrays as a flat rectangular result set, similar to how you would if you were just using SQL directly and joining some data.
If you want to select partial objects you can use the partial DQL keyword.
php console doctrine:query:dql --hydrate array \
'SELECT partial s.{name ,id}, partial c.{name, id }
FROM DatabaseBundle:ProductCategories c
JOIN c.suppliers s ORDER BY s.name, c.name'
print_r($sql);
echo "\n";
print_r($sql_params);
$result = db_query($sql, $sql_params); // Error happening here
Output:
select SQL_CALC_FOUND_ROWS * from rocdocs_database_1318520218 where 1=1 order by ? ? limit ?, ?
Array
(
[0] => c5
[1] => desc
[2] => 0
[3] => 50
)
According to the documentation I can used ordered parameters by using an array and ? marks, but it seems to be erroring. Any ways to debug this? I have installed devel, but it doesn't show the query.
You can't use placeholders for anything that is "sql structure" like sort definitions, table/column names and so on. This is impossible.
If you need dynamic order by definitions, use db_select() and then orderBy(). Make sure to validate what you pass in through that.