how to convert sql command to yii2 - yii2

select g_code
from t_graph_name
where character_length(g_code) = 5

You need to read about build Query in Yii2..also you can read about active record too.
after reading it, you can see you can build it by Query builder like this:
$rows = (new \yii\db\Query())
->select(['g_code'])
->from('t_graph_name')
->where('character_length(g_code) = 5')
->all();

Related

Where is CDbCriteria in Yii2 framework?

$criteria = new CDbCriteria;
$criteria->condition = 'categoryMaster_id=:categoryMaster_id';
I want to get data from multiple tables and show in one JSON. I'm getting error here:
Class 'app\controllers\CDbCriteria' not found.
There is no CDbCriteria in Yii2 - it was mostly replaced by Query and ActiveQuery. You should read Query Builder section (and related) in documentation, and upgrade instructions.
But you probably need something like:
$data = (new \yii\db\Query())
->from('my_table')
->leftJoin('my_joined_table', 'my_joined_table.my_id = my_table.id')
->where('categoryMaster_id=:categoryMaster_id', ['categoryMaster_id' => $id])
->all();

zf2 db sql where datetime before two ours ago

I'm looking for the right zf2 syntax to select timestamps / timeranges from the database. I know how to make where statements. However it seems that greaterThan() and lessThan() are not working with timestamps/datetime:
where = new Where();
$where->lessThan("datecolumn",$vardate);
I want to select all records older than 2 hours. so whats the right way to select date with zend framework 2?
Thx, I really appreciate your help
This works fine (just a sample) -
$select = new Select('album');
$created = date('Y-m-d H:i:s', strtotime("-2 hours"));
$where = new Where();
$where->lessThanOrEqualTo('created', $created);
$select->where($where);
$resultSet = $this->tableGateway->selectWith($select);
Try something like this in your mapper method:
$selectRecords = $this->tableGateway->getSql()->select();
$selectRecords->columns(array('id'))
->where->greaterThanOrEqualTo('dateColumn', $startDate)
->lessThanOrEqualTo('dateColumn', $endDate)
;
$resultSet = $this->tableGateway->selectWith($selectRecords);

Print Sql query in Symfony

I need to findout the normal sql query for the below. Can you guys please suggest me how can i achieve in Symfony.
Example:
$r = Doctrine_Query::create()
->select('u.worked_hours')
->from('tasksComments u')
->where('u.tasks_id = ?', $arr_values['tasks_id'])
->andwhere('u.id != ?', $arr_values['id'])
->andwhere('u.created_at LIKE ?', $date."%");
$results1 = $r->execute();
On the query object, use the method getSQL.
In your case:
$r = Doctrine_Query::create()
->select('u.worked_hours')
->from('tasksComments u')
->where('u.tasks_id = ?', $arr_values['tasks_id'])
->andwhere('u.id != ?', $arr_values['id'])
->andwhere('u.created_at LIKE ?', $date."%");
var_dump($r->getSQL()); // print the SQL query - you will need to replace the parameters in the query
var_dump($r->getParams()); // print the parameters of the query so you can easily replace the missing parameters in the query
Note that I don't know the namespace of Doctrine_Query but I am assuming that your Query object in this Query object in the Doctrine API documentation.
Using Symfony 1.4 with Doctrine 1.2.3
echo $q->getSqlQuery();
You can view all the executed queries in the profiler toolbar by clicking on the db panel icon (the last section of the toolbar) then on the [Display runnable query] link under your query.

Import of 50K+ Records in MySQL Gives General error: 1390 Prepared statement contains too many placeholders

Has anyone ever come across this error: General error: 1390 Prepared statement contains too many placeholders
I just did an import via SequelPro of over 50,000 records and now when I go to view these records in my view (Laravel 4) I get General error: 1390 Prepared statement contains too many placeholders.
The below index() method in my AdminNotesController.php file is what is generating the query and rendering the view.
public function index()
{
$created_at_value = Input::get('created_at_value');
$note_types_value = Input::get('note_types_value');
$contact_names_value = Input::get('contact_names_value');
$user_names_value = Input::get('user_names_value');
$account_managers_value = Input::get('account_managers_value');
if (is_null($created_at_value)) $created_at_value = DB::table('notes')->lists('created_at');
if (is_null($note_types_value)) $note_types_value = DB::table('note_types')->lists('type');
if (is_null($contact_names_value)) $contact_names_value = DB::table('contacts')->select(DB::raw('CONCAT(first_name," ",last_name) as cname'))->lists('cname');
if (is_null($user_names_value)) $user_names_value = DB::table('users')->select(DB::raw('CONCAT(first_name," ",last_name) as uname'))->lists('uname');
// In the view, there is a dropdown box, that allows the user to select the amount of records to show per page. Retrieve that value or set a default.
$perPage = Input::get('perPage', 10);
// This code retrieves the order from the session that has been selected by the user by clicking on a table column title. The value is placed in the session via the getOrder() method and is used later in the Eloquent query and joins.
$order = Session::get('account.order', 'company_name.asc');
$order = explode('.', $order);
$notes_query = Note::leftJoin('note_types', 'note_types.id', '=', 'notes.note_type_id')
->leftJoin('users', 'users.id', '=', 'notes.user_id')
->leftJoin('contacts', 'contacts.id', '=', 'notes.contact_id')
->orderBy($order[0], $order[1])
->select(array('notes.*', DB::raw('notes.id as nid')));
if (!empty($created_at_value)) $notes_query = $notes_query->whereIn('notes.created_at', $created_at_value);
$notes = $notes_query->whereIn('note_types.type', $note_types_value)
->whereIn(DB::raw('CONCAT(contacts.first_name," ",contacts.last_name)'), $contact_names_value)
->whereIn(DB::raw('CONCAT(users.first_name," ",users.last_name)'), $user_names_value)
->paginate($perPage)->appends(array('created_at_value' => Input::get('created_at_value'), 'note_types_value' => Input::get('note_types_value'), 'contact_names_value' => Input::get('contact_names_value'), 'user_names_value' => Input::get('user_names_value')));
$notes_trash = Note::onlyTrashed()
->leftJoin('note_types', 'note_types.id', '=', 'notes.note_type_id')
->leftJoin('users', 'users.id', '=', 'notes.user_id')
->leftJoin('contacts', 'contacts.id', '=', 'notes.contact_id')
->orderBy($order[0], $order[1])
->select(array('notes.*', DB::raw('notes.id as nid')))
->get();
$this->layout->content = View::make('admin.notes.index', array(
'notes' => $notes,
'created_at' => DB::table('notes')->lists('created_at', 'created_at'),
'note_types' => DB::table('note_types')->lists('type', 'type'),
'contacts' => DB::table('contacts')->select(DB::raw('CONCAT(first_name," ",last_name) as cname'))->lists('cname', 'cname'),
'accounts' => Account::lists('company_name', 'company_name'),
'users' => DB::table('users')->select(DB::raw('CONCAT(first_name," ",last_name) as uname'))->lists('uname', 'uname'),
'notes_trash' => $notes_trash,
'perPage' => $perPage
));
}
Any advice would be appreciated. Thanks.
Solved this issue by using array_chunk function.
Here is the solution below:
foreach (array_chunk($data,1000) as $t)
{
DB::table('table_name')->insert($t);
}
There is limit 65,535 (2^16-1) place holders in MariaDB 5.5 which is supposed to have identical behaviour as MySQL 5.5.
Not sure if relevant, I tested it on PHP 5.5.12 using MySQLi / MySQLND.
This error only happens when both of the following conditions are met:
You are using the MySQL Native Driver (mysqlnd) and not the MySQL client library (libmysqlclient)
You are not emulating prepares.
If you change either one of these factors, this error will not occur. However keep in mind that doing both of these is recommended either for performance or security issues, so I would not recommend this solution for anything but more of a one-time or temporary problem you are having. To prevent this error from occurring, the fix is as simple as:
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
While I think #The Disintegrator is correct about the placeholders being limited. I would not run 1 query per record.
I have a query that worked fine until I added one more column and now I have 72k placeholders and I get this error. However, that 72k is made up of 9000 rows with 8 columns. Running this query 1 record at a time would take days. (I'm trying to import AdWords data into a DB and it would literally take more than 24 hours to import a days worth of data if I did it 1 record at a time. I tried that first.)
What I would recommend is something of a hack. First either dynamically determine the max number of placeholders you want to allow - i.e. 60k to be safe. Use this number to determine, based on the number of columns, how many complete records you can import/return at once. Create the full array of data for you query. Use a array_chunk and a foreach loop to grab everything you want in the minimum number of queries. Like this:
$maxRecords = 1000;
$sql = 'SELECT * FROM ...';
$qMarks = array_fill(0, $maxInsert, '(?, ...)');
$tmp = $sql . $implode(', ', $qMarks);
foreach (array_chunk($data, $maxRecords) AS $junk=>$dataArray) {
if (count($dataArray) < $maxRecords)) { break; }
// Do your PDO stuff here using $tmp as you SQL statement with all those placeholders - the ?s
}
// Now insert all the leftovers with basically the same code as above except accounting for
// the fact that you have fewer than $maxRecords now.
Using Laravel model, copy all 11000 records from sqlite database to mysql database in few seconds. Chunk data array to 500 records:
public function handle(): void
{
$smodel = new Src_model();
$smodel->setTable($this->argument('fromtable'));
$smodel->setConnection('default'); // sqlite database
$src = $smodel::all()->toArray();
$dmodel = new Dst_model();
$dmodel->setTable($this->argument('totable'));
$dmodel->timestamps = false;
$stack = $dmodel->getFields();
$fields = array_shift($stack);
$condb = DB::connection('mysql');
$condb->beginTransaction();
$dmodel::query()->truncate();
$dmodel->fillable($stack);
$srcarr=array_chunk($src,500);
$isOK=true;
foreach($srcarr as $item) {
if (!$dmodel->query()->insert($item)) $isOK=false;
}
if ($isOK) {
$this->notify("Przenieśliśmy tabelę z tabeli : {$this->argument('fromtable')} do tabeli: {$this->argument('totable')}", 'Będzie świeża jak nigdy!');
$condb->commit();
}
else $condb->rollBack();
}
You can do it with array_chunk function, like this:
foreach(array_chunk($data, 1000) as $key => $smallerArray) {
foreach ($smallerArray as $index => $value) {
$temp[$index] = $value
}
DB::table('table_name')->insert(temp);
}
My Fix for above issue:
On my side when i got this error I fixed it by reducing the the bulk insertion chunk size from 1000 to 800 and it worked for me.
Actually there were too many fields in my table and most them contains the details descriptions of size like a complete page text. when i go for there bulk insertion the service caused crashed and through the above error.
I think the number of placeholders is limited to 65536 per query (at least in older mysql versions).
I really can't discern what this piece of code is generating. But if it's a gigantic query, There's your problem.
You should generate one query per record to import and put those into a transaction.

Troubles with IN in Yii query builder

I use Yii Framework and i need to build difficult query with many conditions.
I'm filling 2 arrays $conditions and $values.
And i have one problem.
Below is example
When i use
$usersId = '1,2';
$conditions[] = 'e.user_id IN(:usersId)';
$values[':usersId'] = $usersId;
I get only value from user_id = 1
When i'm not use option and write manually
$usersId = '1,2';
$conditions[] = 'e.user_id IN(' . $usersId . ')';
no problem.
Of course i can use second construction, but it seems not very good.
You should addInCondition
$criteria->addInCondition('e.user_id',array(1,2));
Yii way would be to use CDbCriteria addInCondition function
$usersId = array(1,2); //must be array
$criteria=new CDbCriteria();
$criteria->addInCondition('user_id',$usersId);
$result = MyModel::model()->findAll($criteria);
$values[':usersId'] = $usersId;
If I understand your wuestion correctly, you can use the BindParam function in yii?
Instead of this - $values[':usersId'] = $usersId;
Write this - $command->BindParam(':usersId', $usersId, PDO::PARAM_STR);
Very simply, you're binding your parameters to your command statement.
Hope it works!