I can successfully run an xquery FLOWR on an xml doc:
for $result in doc(results.xml)////sparql/results/result/binding
where $result/#name="xyz"
return $result
What if i want to run the same FLOWR on a variable instead?
for $result in $results//sparql/results/result/binding
where $result/#name="xyz"
return $result
this does not work. What's the correct syntax?
If $results is a document node then your syntax is correct.
If $results is a URI containing the location of a document that needs to be parsed, then you want doc($results)//......
Related
I've been trying to query a BaseX db which contains more than 1500000 items.
When i run this query
for $item in collection('coll')//item
return $item (: returns an xml element :)
it executes in less than a second.
But when i try to return the result in an xml I get an "Out of main memory" error.
<xml>{
for $item in collection('coll')//item
return $item
}</xml>
This is something that makes me want to abandon the native xml db approach (same happens with other DBs, such as eXistDB), so if anyone has any info this problem, it would be extremely helpful.
Thanks
Due to the semantics of XQuery, all child nodes need to be copied if they are wrapped by a new parent node. This is demonstrated by the following query, which compares the node identity of the original and copied node. It will yield false:
let $node := <node/>
let $parent := <parent>{ $node }</parent>
return $parent/node is $node
As copying millions of nodes is expensive, this inevitably leads to an out-of-memory error.
If you write results to files, here is a pragmatic solution to get around this restriction:
(:~
: Writes element to a file, wrapped by a root node.
: #param $path path to file
: #param $elements elements to write
: #param $name name of root node
:)
declare function local:write-to(
$path as xs:string,
$elements as element()*,
$name as xs:string
) as empty-sequence() {
file:write-text($path, '<' || $name || '>'),
file:append($path, $elements),
file:append-text($path, '</' || $name || '>')
};
local:write-to('result.xml', <result/>, 'root')
To anticipate criticism: This is a clear hack. For example, the approach conflicts with various non-default serialization parameters of BaseX (the result will not be well-formed if an XML declaration needs to be be output, etc.).
With BaseX 9.0, you can temporarily disable node copying via the COPYNODE option:
(# db:copynode false #) {
<xml>{
for $item in collection('coll')//item
return $item
}</xml>
}
I need get the name of all the tables that exist on my database. I am usin Propel like my ORM. Actully i have been trying on this form.
$dbmap = \Propel::getDatabaseMap('data');
$tablastmp = $dbmap->getTables();
$tablas = array();
foreach ($tablastmp as $tablatmp) {
$tablas[] = $tablatmp->getName();
}
echo '<pre>';
print_r($tablas);
echo '</pre>';
die();
but this return an array that is empty.
array();
And I need that return something like that:
array( [0] => 'clients', [1] => 'workers' );
Please someone help. I have been trying that for a few days.
Actually, you probably wouldn't use Propel to get this information as Propel only loads the table map information when the table is actually used.
The original Schema file is used during the build phase (running 'propel_gen om' etc). The runtime part of Propel never looks at the Schema file, so there is no way to query it per se.
The answer to your question is to look at the database, e.g. the MySQL query to list the tables in a database:
SHOW [FULL] TABLES [{FROM | IN} db_name]
[LIKE 'pattern' | WHERE expr]
This might help you (hopefully)
$em = $this->getDoctrine()->getManager();
foreach ($em->getMetadataFactory()->getAllMetadata() as $md) {
var_dump($md->getName()); // dump the full class names
var_dump($md->getTableName()); // dump the table names
}
I'm trying to update an attribute value of a node and return its previous value all in one query and I can't find a way to do it. I'm using BaseX as my XML/XQuery database.
For now I've tried doing this:
/Root/Elem/properties/property[#id='17']/#format,
replace value of node /Root/Elem/properties/property[#id='17']/#format with 'URL'
and also this:
for $prop in /Root/Elem/properties/property[#id='17']
let $format := $prop/#format
return (replace value of node $prop/#format with 'URL', $format)
And multiple other tests but they all lead to the following error:
List expression: no updating expression allowed.
Is it a limitation of BaseX or is it not possible in XQuery?
XQuery Update does not allow returning results from an updating query. You can however use BaseX's proprietary update:output($seq) function to do that:
for $prop in /Root/Elem/properties/property[#id='17']
let $format := $prop/#format
return (replace value of node $format with 'URL', update:output($format))
I would like to connect to the database from a Drupal 7 module. Currently I only have the query I want to run which is:
$query = db_select('z_lists)
->fields('country')
->condition('value', $country, '=')
->execute()
->fetchAssoc();
What I can't figure out is how to establish a connection to the default database.
Any help?
In Drupal7 there is function called db_query(). you can use that function to run your queries.
You can use below syntex
$var1 = 1;
$result = db_query('SELECT n.title FROM {node} n WHERE n.uid = :uid', array(':uid' => $var1));
$result will be stdClass object so you can use it in foreach loop.
The only problems with the op's example code was a misuse of the db_select and a missing single quote.
Dynamic queries: https://drupal.org/node/310075
It would have been fine if you'd just used this instead:
$query = db_select('z_lists','z')
->fields('z')
->condition('value', $country, '=')
->execute()
->fetchAssoc();
That would return all fields for the matching record(s).
the ->fetchAssoc() chained to the end would ensure you only received the first matching record. If you expected multiple results you'd leave off ->fetchAssoc() and just loop through the results with:
foreach($query as $result){
... do something with the data here ...
}
But to answer the actual ASKED question, you're automatically connected to the default database. There is no need to declare any kind of DB connection before running any kind of query to the site db.
If you're trying to connect to an external database that's a different issue.
Is it possible to return the actual SQL query as a string from the result of db_query?
Or otherwise take the returned resource ID from db_query and get the SQL string?
Edit:
As an addendum, I recently found out about db_queryd() from the Devel module, which echoes the query passed (as well as execute it). Doesn't return the string as this question asked, but really helpful for copying and pasting a complete query.
I don't think it is. However if you are only doing so for the purpose of debugging you can turn on the devel module and that will show you the queries run.
Actually you could just set the variable 'dev_query' to 1 and then access the global array $queries, but I wouldn't recommend it.
Drupal 7, if debug, you could find at \includes\database\database.inc:
function query($query, array $args = array(), $options = array())
$stmt's queryString
or
print_r($stmt->getQueryString());
If you have D7 but don't have Devel to hand, the following snippet could come in useful — it may not handle every type of placeholder however... it currently wrongly assumes all placeholders are strings (which has been fine for my usage).
function stringify_query( $query ){
$s = preg_replace('/\}|\{/', '', $query->__toString());
$a = $query->arguments();
foreach ( $a as $key => $val ) {
$a[$key] = '\'' . $val . '\'';
}
return strtr($s, $a);
}
It also rudely strips out Drupal's curly braces used to handle table prefixes, if you rely on table prefixes then you should find the correct Drupal function to have them replaced correctly.
I would recommend the use of the devel module. There is a setting devel offers which will show all queries run during the generation of a page at the bottom of the page, with data on query execution time and the function that called db_query(). If you have a general idea of what your query will look like or the function that called it, you could search for it within your browser and you can see what was actually send to the database.
Late answer, but you can often turn
$result = db_query($query, $arg1, $arg2);
quickly into
drupal_set_message(sprintf($query, $arg1, $arg2), "status");
And get what you want.
This doesn't help you if you are using an array as your argument to db_query as sprintf doesn't support that, but is often useful in your debugging toolkit.
For those using Drupal 7.x and the Devel module, the correct function to call to output the built SQL statement to the drupal message area is dpq(). It needs to be passed the query object though. e.g.
// to see the built SQL
$query = db_select('node', 'n')->fields('n');
dpq($query);
// to see the results of the query
$results = $query->execute()->fetchAssoc();
dsm($results);
Hope that can help!
D7 version with devel.
>= PHP 5.4
dpm(str_replace(['{', '}'], '', dpq($query, TRUE)));
< PHP 5.4
dpm(str_replace(array('{', '}'), '', dpq($query, TRUE)));