Transform an SQL query in Joomla Jdatabase syntax query? - sql

I know a bit SQL but not at all Jdatabase.
I would like to write this query:
'SELECT deal_id, name FROM products,cities WHERE products.location_id = cities.id'
in Jdatabase syntax.
It should looks like bit:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select(array('name', 'name'))
->from($db->quoteName('#__products','#__cities'))
->where($db->quoteName.....?????????
$db->setQuery($query);
$row = $db->loadRow();
Then after that, I would like to load the result of this query in an array and display one specific value.
I explain: this array would be to display a list of products. Irt will be done by php loop, and on each product , I want to display the city of product by using the array and product_id.
Someone can help please?

Format it Just Like a Sql-Command:
$query->select(array('#__products.name', '#__cities.name'))
->from($db->quoteName(array('#__products','#__cities')))
->where($db->quoteName('#__cities.id') . ' = ' . $db->quoteName('#__products.location_id'))
BUT:::
Consider using an Left JOIN.
$query->select(array('#__products.name', '#__cities.name'))
->from($db->quoteName('#__products'))
->join('LEFT', $db->quoteName('#__cities') . ' ON (' . $db->quoteName('#__cities.id') . ' = ' . $db->quoteName('#__products.location_id') . ')')

Related

Intersect two SQL statement in Yii?

I want to apply an intersect operator on two SQL queries, but I couldn't find any Yii method for it in CDbCommand. Is there any?
Unfortunately there is no INTERSECT operator in Yiis CDbCommand. But you can use "pure" SQL to make queries.
Examples:
$sql = "first select INTERSECT second select";
$result = Yii::app()->db->createCommand($sql)->queryAll();
You could also use CDbCommands for making single queries, just use buildQuery() on them. It will looks like:
$firstSql = 'define sql here';
$firstSql->where('your condition');
$secondSql = 'define sql here';
$secondql->where('your condition');
$sql = buildQuery($firstSql) . ' INTERSECT ' . buildQuery($secondSql);
$result = Yii::app()->db->createCommand($sql)->queryAll();
Hope it will help you!

SQL statement search for all characters inside field

I have an address field and address is stored similar to
1111 address info, county
$stmt = $db->prepare('SELECT * FROM ' . Config::USER_TABLE . ' WHERE ' . Config::SEARCH_COLUMN . ' LIKE :query ORDER BY '.Config::SEARCH_COLUMN.' LIMIT ' . $start . ', ' . $items_per_page);
$search_query = $query.'%';
$stmt->bindParam(':query', $search_query, PDO::PARAM_STR);
At the moment I can only search the field by it is number. I want to be able to type any letter and be able to search. Any ideas??? Thanks
The % sign you attach to your parameter acts as an SQL wildcard:
$search_query = $query.'%';
Since you only attach it to the end of your parameter, it will only search for the string in the beginning of the column values.
Instead, also add one in the beginning of your parameter:
$search_query = '%'.$query.'%';
This way, it will look for the string in any position.
Use %search_criteria% so you can search with wildcards on both sides

What does it mean "?" in sql query?

I just got a query cod :
SELECT o.id,o.sort_order,od.object FROM i_objects o, i_objects_description od
WHERE o.id=od.objects_id AND o.object_status = ? AND od.languages_id = ?
ORDER BY o.sort_order ASC
I want figure it out what does "?" mean in this query ?
If I run this query , it gives me this error :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?
Im using PEAR and this is my function :
function getArrayObjects( $language_id )
{
$q = 'SELECT o.id,o.sort_order,od.object FROM ' . TABLE_OBJECTS . ' o, ' . TABLE_OBJECTS_DESCRIPTION . ' od ';
$q.= 'WHERE o.id=od.objects_id AND o.object_status = ? AND od.languages_id = ? ';
$q.= 'ORDER BY o.sort_order ASC';
$sth = $this->_db->prepare( $q );
$res = $sth->execute( array( 'active', $language_id ) );
//var_dump($res);echo "<br>";echo "<br>";echo "<br>";
$objects = array();
while( $row = $res->fetchRow())
{
$objects[$row['id']] = $row;
}
return $objects;
}
It's a placeholder for parameter. In your query you have this:
AND o.object_status = ? AND od.languages_id = ?
And then you execute it like this:
$res = $sth->execute( array( 'active', $language_id ) );
So, when query is actually executed by database server, object_status is 'active' and language_id is $language_id.
This is done this way to guard from SQL injection. Another reason is efficiency. When you use prepared statements, database doesn't need to parse/compile query each time. It uses the template and just substitutes values in it. (more on this: Prepared statement)
The ? are placeholder the values of which are filled in in the $sth->execute( array( 'active', $language_id ) ) statement.
One of the main purposes for this construct is to prevent sql injection attacks.
Its a Used to set the value dynamically ,in other words place holder
These are "parametrized queries". While evaluating "?" are replaced with given values (it's called binding). They protect from sql injection and makes possible to optimize queries.

Zend_Db_Select with 'FOR XML PATH' for SQL Server

I'm trying to code the following query using Zend_Db_Select:
SELECT p1.SKU,
(
SELECT ',' + Status
FROM "Products" "p2"
WHERE p2.SKU = p1.SKU
ORDER BY "Status"
FOR XML PATH ('')
) AS "Statuses"
FROM "Products" p1
GROUP BY SKU
This is what I have so far:
$s1 = $products->select()
->setIntegrityCheck(false)
->from(array('p2' => 'Products'),
new Zend_Db_Expr("',' + Status")
)
->where('p2.SKU = p1.SKU')
->order('Status');
$s2 = $products->select()
->from(array('p1' => 'Products'),
array('p1.SKU',
'Statuses' => new Zend_Db_Expr('(' . $s1 . ')')
)
)
->group('SKU');
echo $s2;
$dbRowSet = $Products->fetchAll($s2);
That gives me this:
SELECT "p1"."SKU",
(
SELECT ',' + Status
FROM "Products" AS "p2"
WHERE (p2.SKU = p1.SKU)
ORDER BY "Status" ASC
) AS "Statuses"
FROM "Products" AS "p1"
GROUP BY "SKU"
I can't figure out how to get the required FOR XML PATH ('').
Also, isn't using the . operator with $s1 calling __toString(), instead of leaving it as a native Zend_Db_Select object. Is there any other way to get the parens around $s1?
Alternatively, is there another way to do this whole query? I want to return each SKU and a concatenated grouping of all Statuses (a la GROUP_CONCAT() in MySQL). The table is huge, so iterating over them in PHP takes an unacceptably long time.
Unfortunately Zend Framework does not have a great support for constructing MS SQL specific queries. What you could do is use Zend_Db_Adapter_Abstract::query() and skip the object oriented query abstraction altogether. Alternatively, you could extend the Zend_Db_Select, add the appropriate code to Zend_Db_Select::$_parts and Zend_Db_Select::_render*, however you would still have an incomplete support.
I don't quite understand what exactly are you doing in the second code example, since the $2 variable is not assigned at all.
Don't worry about the __toString() being called when you use . for string construction; the expression will ultimately be subjected to string conversion either way.
Looks like I was close, and with KSiimson's comments about string conversion in mind, this works:
$s1 = $products->select()
->setIntegrityCheck(false)
->from(array('p2' => 'Products'),
new Zend_Db_Expr("',' + Status")
)
->where('p2.SKU = p1.SKU')
->order('Status');
$s2 = $products->select()
->from(array('p1' => 'Products'),
array('p1.SKU',
'Statuses' => new Zend_Db_Expr('(' . $s1 .
" FOR XML PATH(''))")
)
)
->group('SKU');
echo $s2;
$dbRowSet = $Products->fetchAll($s2);
This just concats the FOR XML PATH clause with the first query as a string. Not quite as elegant as I was hoping for, but "perfect is the enemy of good".

Is there SQL parameter binding for arrays?

Is there a standard way to bind arrays (of scalars) in a SQL query? I want to bind into an IN clause, like so:
SELECT * FROM junk WHERE junk.id IN (?);
I happen to be using Perl::DBI which coerces parameters to scalars, so I end up with useless queries like:
SELECT * FROM junk WHERE junk.id IN ('ARRAY(0xdeadbeef)');
Clarification: I put the query in its own .sql file, so the string is already formed. Where the answers mention creating the query string dynamically I'd probably do a search and replace instead.
Edit: This question is kind of a duplicate of Parameterizing a SQL IN clause?. I originally thought that it should be closed as such, but it seems like it's accumulating some good Perl-specific info.
If you don't like the map there, you can use the 'x' operator:
my $params = join ', ' => ('?') x #foo;
my $sql = "SELECT * FROM table WHERE id IN ($params)";
my $sth = $dbh->prepare( $sql );
$sth->execute( #foo );
The parentheses are needed around the '?' because that forces 'x' to be in list context.
Read "perldoc perlop" and search for 'Binary "x"' for more information (it's in the "Multiplicative Operators" section).
You specify "this is the SQL for a query with one parameter" -- that won't work when you want many parameters. It's a pain to deal with, of course. Two other variations to what was suggested already:
1) Use DBI->quote instead of place holders.
my $sql = "select foo from bar where baz in ("
. join(",", map { $dbh->quote($_) } #bazs)
. ")";
my $data = $dbh->selectall_arrayref($sql);
2) Use an ORM to do this sort of low level stuff for you. DBIx::Class or Rose::DB::Object, for example.
I do something like:
my $dbh = DBI->connect( ... );
my #vals= ( 1,2,3,4,5 );
my $sql = 'SELECT * FROM table WHERE id IN (' . join( ',', map { '?' } #vals ) . ')';
my $sth = $dbh->prepare( $sql );
$sth->execute( #vals );
And yet another way to build SQL is to use something like SQL::Abstract....
use SQL::Abstract;
my $sql = SQL::Abstract->new;
my $values = [ 1..3 ];
my $query = $sql->select( 'table', '*', { id => { -in => $values } } );
say $query; # => SELECT * FROM table WHERE ( id IN ( ?, ?, ? ) )
With plain DBI you'd have to build the SQL yourself, as suggested above. DBIx::Simple (a wrapper for DBI) does this for you automatically using the '??' notation:
$db->query("select * from foo where bar in (??)", #values);
In python, I've always ended up doing something like:
query = 'select * from junk where junk.id in ('
for id in junkids:
query = query + '?,'
query = query + ')'
cursor.execute(query, junkids)
...which essentially builds a query with one '?' for each element of the list.
(and if there's other parameters in there too, you need to make sure you line things up correctly when you execute the query)
[edit to make the code easier to understand for non-python people. There is a bug, where the query will have an extra comma after the last ?, which I will leave in because fixing it would just cloud the general idea]
I use DBIx::DWIW. It contains a function called InList(). This will create the part of the SQL that is needed for the list. However this only works if you have all your SQL in the program instead of outside in a separate file.
Use
SELECT * FROM junk WHERE junk.id = ANY (?);
instead