I am building a custom artisan command that needs to be able to access the database's default values for certain columns. I cannot use the attributes array. So instead I need another way.
I have tried to use Schema. I have been able to get the table DB::table($table) and the column names Schema::getColumnListings($table) but not the default values.
Is there some other way to get the default values?
The Laravel Schema Builder only returns column names by design. But you can use the same approach Laravel uses internally by executing a database statement:
$results = DB::select('
select column_default
from information_schema.columns
where
table_schema = ?
and table_name = ?
', [$database, $table]);
// Flatten the results to get an array of the default values
$defaults = collect($results)->pluck('column_default'))
The above example works for a MySQL database, but you can see the approaches for other databases in the Illuminate\Database\Schema\Grammars namespace of the Laravel source code by searching for the method compileColumnListing.
In Laravel 5+ (including 6 and 7), you can get the db table column metadata (ie type, default value etc) in the following way:
use Illuminate\Support\Facades\Schema;
For all columns:
$columns = Schema::getConnection()->getDoctrineSchemaManager()->listTableColumns('table_name');
For a single column:
$column = Schema::getConnection()->getDoctrineColumn('table_name'', 'column_name');
getDoctrineSchemaManager method returns a array of \Doctrine\DBAL\Schema\Column Class Instances. By using this you can get everything about a db table column.
getDoctrineColumn method returns the instance of \Doctrine\DBAL\Schema\Column class.
Couple of methods from \Doctrine\DBAL\Schema\Column class:
$column->getName();
$column->getNotnull(); // returns true/false
$column->getDefault();
$column->getType();
$column->getLength();
I have this query in laravel 5.2
$obj_custom_stdy_data = QstCustomStudyData::where('student_id', $this->data_user['student_id'])
->select($list_id . ' as list_id ', 'chapter_id', 'subject_id', 'subject_code_id')
->get()
->toArray();
Well I have a fixed value $list_id got from top code. Actually I want to add new field during query selection as list_id. However I got error for such that method.
When I tried in mysql IDE for example:
SELECT (1+2) as total, c.* FROM users
Then the result is no wrong at all.
Is that anyway to write in query builder for laravel instead of raw style?
You can take the use of DB::raw() method of QueryBuilder like this:
->select(DB::raw('(1+2) as total'));
See more about Query Builder's Raw Expressions
Hope this helps!
I need to eliminate the specific prefix of a string by default on getting value from the database.
In MySQL, i can use the following,
SELECT RIGHT('abc3',1) -- Results in "3"
SELECT RIGHT('abc3',2) -- Results in "c3"
But, how can i use same process in Laravel eloquent?.
Or any other solutions are available for remove the prefix of a string while retrieve from database in laravel.
I know trim will eliminate, but only spaces.
ex.
property_color
property_size
Here i need to extract "property_".
expect.
color
size
Is it possible in laravel, in without using PHP String function.
Only on Direct eloquent Operation.
Thanks in Advance !
That's what I would do:
$arrayData = DB::select(DB::raw("SELECT RIGHT('abc3',1) ")):
you can pass array of parameter to bind values:
DB::select(DB::raw(" SQL QUERY "),$paramsArray);
You have to use raw queries within your builder like
$results = YourRepo::where(DB::raw("SELECT SUBSTRING('property_color',9)") , 'LIKE', "%property_xxx%");
keep in mind that substring is slow.
I'm trying get a single value from MySQL database using laravel but the problem I'm getting an array . this is my query result in MySQL command line:
select groupName from users;
+-----------+
| groupName |
+-----------+
| Admin |
+-----------+
my laravel function:
public static function PermitAddNewUser(){
$username=Session::get('key');
$data=DB::select("select groupName from users where username='$username';");
return $data;
}
expected $data value is a string with value= Admin
but what i get is : [{"groupName":"Admin"}]
yet another edit: As of version 5.2 pluck is not deprecated anymore, it just got new behaviour (same as lists previously - see side-note below):
edit: As of version 5.1 pluck is deprecated, so start using value instead:
DB::table('users')->where('username', $username)->value('groupName');
// valid for L4 / L5.0 only
DB::table('users')->where('username', $username)->pluck('groupName');
this will return single value of groupName field of the first row found.
SIDE NOTE reg. #TomasButeler comment: As Laravel doesn't follow sensible versioning, there are sometimes cases like this. At the time of writing this answer we had pluck method to get SINGLE value from the query (Laravel 4.* & 5.0).
Then, with L5.1 pluck got deprecated and, instead, we got value method to replace it.
But to make it funny, pluck in fact was never gone. Instead it just got completely new behaviour and... deprecated lists method.. (L5.2) - that was caused by the inconsistency between Query Builder and Collection methods (in 5.1 pluck worked differently on the collection and query, that's the reason).
Edit:
Sorry i forgot about pluck() as many have commented :
Easiest way is :
return DB::table('users')->where('username', $username)->pluck('groupName');
Which will directly return the only the first result for the requested row as a string.
Using the fluent query builder you will obtain an array anyway.
I mean The Query Builder has no idea how many rows will come back from that query.
Here is what you can do to do it a bit cleaner
$result = DB::table('users')->select('groupName')->where('username', $username)->first();
The first() tells the queryBuilder to return only one row so no array, so you can do :
return $result->groupName;
Hope it helps
As of Laravel >= 5.3, best way is to use value:
$groupName = \App\User::where('username',$username)->value('groupName');
or
use App\User;//at top of controller
$groupName = User::where('username',$username)->value('groupName');//inside controller function
Of course you have to create a model User for users table which is most efficient way to interact with database tables in Laravel.
[EDIT]
The expected output of the pluck function has changed from Laravel 5.1 to 5.2. Hence why it is marked as deprecated in 5.1
In Laravel 5.1, pluck gets a single column's value from the first result of a query.
In Laravel 5.2, pluck gets an array with the values of a given column. So it's no longer deprecated, but it no longer do what it used to.
So short answer is use the value function if you want one column from the first row and you are using Laravel 5.1 or above.
Thanks to Tomas Buteler for pointing this out in the comments.
[ORIGINAL]
For anyone coming across this question who is using Laravel 5.1, pluck() has been deprecated and will be removed completely in Laravel 5.2.
Consider future proofing your code by using value() instead.
return DB::table('users')->where('username', $username)->value('groupName');
Using query builder, get the single column value such as groupName
$groupName = DB::table('users')->where('username', $username)->pluck('groupName');
For Laravel 5.1
$groupName=DB::table('users')->where('username', $username)->value('groupName');
Or, Using user model, get the single column value
$groupName = User::where('username', $username)->pluck('groupName');
Or, get the first row and then split for getting single column value
$data = User::where('username', $username)->first();
if($data)
$groupName=$data->groupName;
Continuing, here is how you do it in Laravel 7.x or 8.x
$email = DB::table('users')->where('name', 'John')->value('email');
source: trust me
Updated based on #Shuhad zaman comment
On laravel 5.6 it has a very simple solution:
User::where('username', $username)->first()->groupName;
It will return groupName as a string.
I have the following in Laravel 4.x using eloquent:
Book table has a dozen fields.
$single_data = Book::
selectRaw("GROUP_CONCAT(DISTINCT CAST(id as char) SEPARATOR ',') as type_id_list")
->first();
Question: the data returned is everything within the table inside Book AND type_id_list as seen from the selectRaw.
I would like to ONLY return what I specified within the selectRaw.
It was suggested that you get add an array of columns within first() or get() in order to retrieve this only - however it is not working with custom selectRaw where you specify an expression or your own wording. It throws an error and when the query is analyzed the array that you put in first/get gets appended as part of the select.
Does anyone have a work around?
first() will return only that particular column but wrapped in a Book object anyway, so use pluck() instead:
$single_data = Book::
selectRaw("GROUP_CONCAT(DISTINCT CAST(id as char) SEPARATOR ',') as type_id_list")
->pluck('type_id_list');