In Typo3 version 6.1, I have written some custom queries in My extension Repository
for example in file Mytest/Classes/Domain/Repository/MytestRepository.php
class MytestRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function myFunction(){
$sql = 'SELECT * FROM some_table ';
$sqlResult = $GLOBALS['TYPO3_DB']->sql_query($sql);
while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($sqlResult)) {
$rowone = $row['rowone'];
}
}
}
And calling that function in controller
$test = $this->MytestRepository->myFunction();
But the issue here is, I am getting error
Fatal error: Call to a member function fetch_assoc() on a non-object in /home/src/typo3_src-6.1.1/typo3/sysext/core/Classes/Database/DatabaseConnection.php on line 1029
Anybody have the solution ?
Thanks in advance.
You can execute custom queries like this:
$query = $this->createQuery();
$query->statement('SELECT * FROM some_table');
$result = $query->execute();
If you don't want to get objects as a result from the query, which i assume looking at your while loop, you can set the following line before executing the query:
$query->getQuerySettings()->setReturnRawQueryResult(TRUE);
With setReturnRawQueryResult you get a plain array as a result.
Related
I have the problem that the backend users can set a word with a "" character, for example something like "Test­ ;labor".
If someone uses the frontend search with the word "Testlabor" no match will be found.
In the extbase repository I used this:
$query->like('name', '%' . $searchWord . '%')
I can change that to something like this:
$query->statement("SELECT * FROM table WHERE hidden = 0 AND REPLACE(name,'', '') LIKE '%$searchWord%'")
Then the word will be found but I have to check all the things the framework normally does, like check if it's hidden and deleted and more complicated, if the result is in the right site tree. Now I just get everything that matches the searchword.
Is there a better way to search for words which have "" inside? Can I use something like that within the TYPO3 query builder?
Many thanks in advance.
You can try with QueryBuilder interface
public function findShy($searchWord)
{
/** #var ConnectionPool $pool */
$pool = GeneralUtility::makeInstance(ConnectionPool::class);
$connection = $pool->getConnectionForTable('table');
$queryBuilder = $connection->createQueryBuilder();
$query = $queryBuilder
->select('*')
->from('table')
->where("REPLACE(name,'', '') like :name")
->setParameter('name', "%{$searchWord}%");
// for debug only
echo($query->getSQL());
print_r($query->getParameters());
return $query->execute()->fetchAll();
}
and call it somewhere i.e. in your controller:
DebuggerUtility::var_dump(
$this->yourRepository->findShy('Testlabor'),
'findShy() sample'
);
it will create a query with named parameter like (according to your TCA of course):
SELECT *
FROM `table`
WHERE (REPLACE(name, '', '') like :name)
AND ((`table`.`deleted` = 0) AND (`table`.`hidden` = 0) AND
(`table`.`starttime` <= 1596363840) AND
((`table`.`endtime` = 0) OR (`table`.`endtime` > 1596363840)))
Note that returns associative array with the record not a mapped object of your model.
Optional
If you need mapped model objects anyway, you can mix these two solutions, i.e. first select only the pids of your records with QueryBuilder and then fetch them with Query which implements QueryInterface like this:
public function findShy2($searchWord)
{
/** #var ConnectionPool $pool */
$pool = GeneralUtility::makeInstance(ConnectionPool::class);
$connection = $pool->getConnectionForTable('table');
$queryBuilder = $connection->createQueryBuilder();
$preQuery = $queryBuilder
->select('uid')
->from('table')
->where("REPLACE(name,'', '') like :name")
->setParameter('name', "%{$searchWord}%");
// for debug only
echo($query->getSQL());
print_r($query->getParameters());
$uids = [];
foreach ($preQuery->execute()->fetchAll() as $item) {
$uids[] = $item['uid'];
}
if(count($uids) > 0){
$interfaceQuery = $this->createQuery();
$interfaceQuery->matching(
$interfaceQuery->in('uid', $uids)
);
return $interfaceQuery->execute();
}
return [];
}
I have this actual code
public function findCode($code_received)
{
$pellicules =
$this->createQueryBuilder()
->field('code_base')->equals($code_received)
->getQuery()
;
}
But sometimes my code received is inside my code_base, for example:
Code_received = Abata
Code_base = Abata23xiub
I tried to use the in instead of equals but I'm not having success. How could I do it?
How would I write an Zend DB query to select all from the column ID?
So far I have tried:
public function getLatestUserID()
{
$ids = $this->select()
->where('id = ?');
return $ids;
}
But to no avail.
You just want the id column,
You failed to call an execute command.
try:
//assuming you are using a DbTable model
public function getLatestUserID()
{
$ids = $this->fetchAll('id');
return $ids;
}
I would do it like this, because I use the select() object for everything:
public function getLatestUserID()
{
$select = $this->select();
//I'm not sure if $this will work in this contex but you can out the table name
$select->from(array($this), array('id'));
$ids = $this->fetchAll($select);
return $ids;
}
The first two examples should return just the id column of the table, now if you actually want to query for a specific id:
public function getLatestUserID($id)
{
$select = $this->select();
$select->where('id = ?', $id);
//fetchAll() would still work here if we wanted multiple rows returned
//but fetchRow() for one row and fetchRowset() for multiple rows are probably
//more specific for this purpose.
$ids = $this->fetchRow($select);
return $ids;
}
make sure your class containing getLatestUserID does extend Zend_Db_Table_Abstract also :
$ids = $this->select()->where('id = ?'); can't work because where('id = ?'); expects an id value like where('id = ?', $id);
if what you want is the latest inserted row's Id use :
$lastInsertId = $this->getAdapter()->lastInsertId();
(however if you are using an oracle database this will not work and you should use $lastInsertId = $this->getAdapter()->lastSequenceId('USER_TABLE_SEQUENCE'); )
I get a really anoying error when I try to edit an entry from a table, in tutorial they always use getTable()->find(), but I need to verify that the person logged in is the owner of that entry here what I did:
In the action:
public function executeEdit(sfWebRequest $request)
{
$id = $request->getParameter('id');
$userid = $this->getUser()->getGuardUser()->getId();
$ad = Doctrine_Core::getTable('BambinbazarArticles')->getMyAd($id, $userid);
$this->forward404Unless($ad, sprintf('Object bambinbazar_articles does not exist (%s).', $request->getParameter('id')));
$this->form = new BambinbazarArticlesForm($ad);
}
In the model:
public function getMyAd($id, $userid)
{
$q = $this->createQuery('c')
->where('c.id = ? ', $id)
->addWhere('c.userid = ? ', $userid);
return $q->execute();
}
I tried it with and without the ->execute(), did doctrine clean, cleared cache, rebuilded model,
Always get the same error 'The "%s" form only accepts a "%s" object.
If I use the Doctrine_Core::getTable('BambinbazarArticles')->find() it work, but of course, i need more than that..
I am becoming crazy over this.
execute() can return multiple rows; effectively you're getting a recordset back, rather than the individual object that your form is expecting. Try fetching a single object, using, e.g.:
return $q->execute()->getFirst();
or
return $q->fetchOne();
Its probably because your query is returning a Doctrine_Collection, not the actual Doctrine_Record youre expecting. Instead of execute use fetchOne.
public function getMyAd($id, $userid)
{
$q = $this->createQuery('c')
->where('c.id = ? ', $id)
->addWhere('c.userid = ? ', $userid)
->limit(1);
return $q->fetchOne();
}
I apologize if my title is a bit misleading and it turns out that it's some other class under Zend_Db.
I use the following method of extracting data from a MSSQL:
// $_config contains information about how to connect to my MSSQL server
$config = new Zend_Config($_config);
$db = Zend_Db::factory($config->database);
$sql = "SELECT * FROM table1";
print_r($db->fetchAll($sql));
So far no problem and everything runs smooth :).
Now I need to run some more complex queries with multiple rowsets:
$sql2 = <<<EOD
DECLARE #test INT
SET #test = 42
SELECT * FROM table1 WHERE col1 = #test
SELECT col2 FROM table2 UNION
SELECT col3 FROM table2
SELECT * FROM table3
EOD;
print_r($db->fetchAll($sql2));
I hope you get the idea.
Using $db->fetchAll($sql2); will result in
Fatal error: Uncaught exception
'Zend_Db_Statement_Exception' with
message 'SQLSTATE[HY000]: General
error: 10038 Attempt to initiate a new
SQL Server operation with results
pending. [10038] (severity 7)
[(null)]' in
\Sacp026a\sebamweb$\prod\includes\Zend\Db\Statement\Pdo.php:234
The following function will return all the correct rowsets:
function sqlquery_multiple($zdb, $sql) {
$stmt = $zdb->query($sql);
$rowsets = array();
do {
if ($stmt->columnCount() > 0) {
$rowsets[] = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
} while ($stmt->nextRowset());
return $rowsets;
}
print_r(sqlquery_multiple($db, $sql2));
Now my big question is:
How do I extend Zend_Db, so I can implement and use the function above as $db->fetchMulti($sql2); instead of sqlquery_multiple($db, $sql2)?
Thanks in advance :)
NB: It's worth mentioning that I'm using the ODBC-patch in order to be able to fetch multiple rowsets in the first place.