Convert normal SQL query to Zend_Db? - database

I cant convert this below query to Zend_Db:
SELECT `mfaq`.* FROM `m_faq` AS `mfaq`
WHERE (mfaq.delete_flg <> 'D' OR mfaq.delete_flg IS NULL)
AND ((mfaq.title like '%$title%')
OR (mfaq.title like '%$title%')
AND (mfaq.title like '%$title%')
OR (mfaq.title like '%$title%'))
ORDER BY `create_date` DESC
Some help???

First you need to have created dbtable model:
class Application_Model_DbTable_Mfaq extends Zend_Db_Table_Abstract
{
protected $_name = 'm_faq';
}
Then use it as follows:
$table = new Application_Model_DbTable_Mfaq();
$select = $table->getAdapter()->select()
->from(array('mfaq'=>$table->info(Zend_Db_Table::NAME)))
->where("( mfaq.delete_flg <> 'D'")
->orWhere("mfaq.delete_flg IS NULL )")
->where("( mfaq.title like ?", "%$title%")
->orWhere("mfaq.title like ? ", "%$title%")
->where(" mfaq.title like ?", "%$title%")
->orWhere("mfaq.title like ? )", "%$title%")
->order("create_date DESC");
// echo $select; // shows your sql
$results = $select->query()->fetchAll();
I hope, you take into account that AND have higher priority than OR.

Related

linq2db - server side bulkcopy

I'm trying to do a "database side" bulk copy (i.e. SELECT INTO/INSERT INTO) using linq2db. However, my code is trying to bring the dataset over the wire which is not possible given the size of the DB in question.
My code looks like this:
using (var db = new MyDb()) {
var list = db.SourceTable.
Where(s => s.Year > 2012).
GroupBy(s => new { s.Column1, s.Column2 }).
Select(g => new DestinationTable {
Property1 = 'Constant Value',
Property2 = g.First().Column1,
Property3 = g.First().Column2,
Property4 = g.Count(s => s.Column3 == 'Y')
});
db.Execute("TRUNCATE TABLE DESTINATION_TABLE");
db.BulkCopy(new BulkCopyOptions {
BulkCopyType = BulkCopyType.MultipleRows
}, list);
}
The generated SQL looks like this:
BeforeExecute
-- DBNAME SqlServer.2017
TRUNCATE TABLE DESTINATION_TABLE
DataConnection
Query Execution Time (AfterExecute): 00:00:00.0361209. Records Affected: -1.
DataConnection
BeforeExecute
-- DBNAME SqlServer.2017
DECLARE #take Int -- Int32
SET #take = 1
DECLARE #take_1 Int -- Int32
SET #take_1 = 1
DECLARE #take_2 Int -- Int32
...
SELECT
(
SELECT TOP (#take)
[p].[YEAR]
FROM
[dbo].[SOURCE_TABLE] [p]
WHERE
(([p_16].[YEAR] = [p].[YEAR] OR [p_16].[YEAR] IS NULL AND [p].[YEAR] IS NULL) AND ...
...)
FROM SOURCE_TABLE p_16
WHERE p_16.YEAR > 2012
GROUP BY
...
DataConnection
That is all that is logged as the bulkcopy fails with a timeout, i.e. SqlException "Execution Timeout Expired".
Please note that running this query as an INSERT INTO statement takes less than 1 second directly in the DB.
PS: Anyone have any recommendations as to good code based ETL tools to do large DB (+ 1 TB) ETL. Given the DB size I need things to run in the database and not bring data over the wire. I've tried pyspark, python bonobo, c# etlbox and they all move too much data around. I thought linq2db had potential, i.e. basically just act like a C# to SQL transpiler but it is also trying to move data around.
I would suggest to rewrite your query because group by can not return first element. Also Truncate is a part of the library.
var sourceQuery =
from s in db.SourceTable
where s.Year > 2012
select new
{
Source = s,
Count = Sql.Ext.Count(s.Column3 == 'Y' ? 1 : null).Over()
.PartitionBy(s.Column1, s.Column2).ToValue()
RN = Sql.Ext.RowNumber().Over()
.PartitionBy(s.Column1, s.Column2).OrderByDesc(s.Year).ToValue()
};
db.DestinationTable.Truncate();
sourceQuery.Where(s => s.RN == 1)
.Insert(db.DestinationTable,
e => new DestinationTable
{
Property1 = 'Constant Value',
Property2 = e.Source.Column1,
Property3 = e.Source.Column2,
Property4 = e.Count
});
After some investigation I stumbled onto this issue. Which lead me to the solution. The code above needs to change to:
db.Execute("TRUNCATE TABLE DESTINATION_TABLE");
db.SourceTable.
Where(s => s.Year > 2012).
GroupBy(s => new { s.Column1, s.Column2 }).
Select(g => new DestinationTable {
Property1 = 'Constant Value',
Property2 = g.First().Column1,
Property3 = g.First().Column2,
Property4 = g.Count(s => s.Column3 == 'Y')
}).Insert(db.DestinationTable, e => e);
Documentation of the linq2db project leaves a bit to be desired however, in terms of functionality its looking like a great project for ETLs (without horrible 1000s of line copy/paste sql/ssis scripts).

How to show Data Use "Stored Procedure (Exec) Query SQL Server" codeigniter

CI_Controller ..
public function index(){
$this->load->database();
$this->load->model('model_contoh');
$data = $this->model_contoh->GetDataByProc();
echo '<pre>' ;
print_r($data->result_array());
}
}
CI_Model ..
function GetDataByProc(){
$data = $this->db->query("spCekSelisihJurnal '1/1/2018 00:00:00','12/31/2018 23:00:00'");
return $data ; }}
if this query execute in sql tool success to show the data
but not run in codeigniter ?
enter image description here
Do you not call like this. P1 and P2 would need to need procedure parameter names
$p_1 = '1/1/2018 00:00:00'
$p_2 = '12/31/2018 23:00:00'
$stored_procedure = "CALL spCekSelisihJurnal(?,?) ";
$result = $this->db->query($stored_pocedure,array('P1'=>$p_1,'P2'=>$p_2));

Can Any one help me to convert this sql query into linq

I need to convert this SQL Query to Link :
"Select * FROM [Register]
where RegisterId IN (SELECT MyId
FROM Friends
WHERE FriendId='" + Session["CurrentProfileId"] + "'
AND Status=1
UNION
SELECT FriendId
FROM Friends
WHERE MyId='" + Session["CurrentProfileId"] + "'
AND Status=1) ";
It may be look like this??? but this is incorrect and having errors
(from u in db.Register
where RegisterId).Contains
(from f in db.Freinds
where f.MyId == Id && m.Status == 1
select new { m.MyId })
.Union(from m in db.Freinds
where f.FreindId == Id && m.Status == 1
select new { m.CreateDate } ));
You have a few problems with the linq above and here are a few:
In the query in the Union you select the CreateDate whereas in the top on you select the MyId. I assume you meant to select FreindId.
In these 2 queries you create an anonymous class instance with the field but then compare it to the RegisterId which is probably a guid/string/int - but for sure not of the type you just created.
You are using the Contains method wrong. Linq syntax can be similar to sql but it is not the same. Check here for Contains
The correct Linq way of doing it is:
var idsCollection = ((from f in db.Freinds
where f.StatusId == 1 && f.MyId == Id
select f.MyId)
.Union(from m in db.Friends
where m.StatusId == 1 && f.FreindId == Id
select m.FriendId)).ToList();
var result = (from u in db.Register
where idsCollection.Contains(u.RegisterId)
select u).ToList();
Notice that the .ToList() is not a must and is here just to ease in debugging. For more information about this .ToList() and Linq in general check MSDN

Print SQL query of ORM query builder in cakephp3

How to print ORM query
$query = $articles->find('all')->contain(['Comments']);
For example print =>
SELECT * FROM comments WHERE article_id IN (comments);
Wrapping your ORM query result with the debug function will show the SQL and bound params:
debug($query);
You can also similarly look at the query results with the debug function.See CakePHP 3: retrieving data and result sets — Debugging Queries and ResultSets
what about $query->sql()?
$qb = $this->Person->find()->select(["id", "text" => "concat(Name,' ',Family)"])
->where(['id >' => 0])
->where($query ? ["OR" => $filters] : null)
->limit(10);
dd($qb->sql());
and result:
.../src/Controller/ClientController.php (line 86)
'SELECT Person.id AS `Person__id`, concat(Name,' ',Family) AS `text` FROM person Person WHERE (id > :c0 AND (Family like '%sam%' OR Name like '%sam%' OR Family like '%sam%' OR Name like '%sam%')) LIMIT 10'
I prefer this:
public function __debugInfo()
{
return [
'query' => $this->_query,
'items' => $this->toArray(),
];
}
// Print the query
debug($query->__debugInfo()['sql']);
// Prints this
SELECT * FROM comments WHERE article_id IN (comments);

Using concatenated results individually

I got a complicated query which produces a concatenated result. However, although GROUP_CONCAT is necessary for other purposes, I still need to be able to use the pieces of the concatenated string individually.
GROUP_CONCAT(id, name, date AS concat1
echo $db_field['concat1'];
...produces this output: IdNameDate, and I need to be able to use (and echo) Id, Name and Date separately. I guess it must be assigned to an array, I'm a begginer in PHP and I really appreciate any help.
For sake of simplicity, above I have used id instead of eventid, name instead of eventname and date instead of eventstartdate. Below is the full code.
if ($db_found) {
$SQL ="
select sportname,
tournament_templatename,
tournament_stagename,
GROUP_CONCAT(eventid, eventname, eventstartdate SEPARATOR '<br />' ) as concat1
from (
SELECT event.id AS eventid,
event.name AS eventname,
event.tournament_stageFK AS eventtournamentstageFK,
event.startdate AS eventstartdate,
tournament_stage.id AS tournament_stageid,
tournament_stage.name AS tournament_stagename,
tournament_stage.tournamentFK AS tournament_stagetournamentFK,
tournament.id AS tournamentid,
tournament.name AS tournamentname,
tournament.tournament_templateFK AS tournamenttournament_templateFK,
tournament_template.id AS tournamenttemplateid,
tournament_template.name AS tournament_templatename,
tournament_template.sportFK AS tournament_templatesportFK,
sport.id AS sportid,
sport.name AS sportname
FROM
event INNER JOIN tournament_stage ON event.tournament_stageFK=tournament_stage.id
INNER JOIN tournament ON tournament_stage.tournamentFK=tournament.id
INNER JOIN tournament_template
ON tournament.tournament_templateFK=tournament_template.id
INNER JOIN sport ON tournament_template.sportFK=sport.id
WHERE
DATE(event.startdate) = CURRENT_DATE()
) a
group by sportname, tournament_templatename, tournament_stagename
order by sportid, tournament_templatename, tournament_stagename";
$result = mysql_query($SQL);
if($result === FALSE) {
die(mysql_error());
}
while($db_field=mysql_fetch_assoc($result)){
echo $db_field['concat1'];
}
mysql_close($db_handle);
}
I either need a way to get back to results before concatenating them, or a way to display IdNameDate as Id*Name*Date so I can use * as an explode delimiter.
Something like this?
$group = array();
$fields = array();
$fields['id'] = 2;
$fields['name'] = "test";
$fields['date'] = "2010/02/13";
$group["test"] = $fields;
To get an individual field:
echo $group["test"]["id"];
To get a whole group line:
echo implode(",", $group["test"]); // change "," to any delimiter character
To get all group lines:
foreach($group as $key => $g)
echo $key.":".implode(",", $g).";"; // change "," to any delimiter character
Hope this helps...
I guess the only way to do it is to:
Explode the GROUP_CONCAT results to get individual strings
Use substr to extract Id, Name and Date from each result as Id and Date are consistent, they always have the same number of characters
In the end, GROUP_CONCAT does more harm than good.

Resources