Retrieve json data from array using select - php

Lets say I have this info stored in my database, in a JSON format.
ROW with id=23: {
"age":50,
"name":"Nick",
"messages":["msg 1","msg 2","msg 3"]
}
ROW with id=24: {
"age":22,
"name":"John",
"messages":["msg 4","msg 3","msg 9"]
}
Now, all I want is to perform an SQL query using PHP to retrieve rows that contains the message msg 3.
How can I do that?
Any advice will be appreciated.
Thanks

Using LIKE '%%' is performance overkill, try to avoid that.
Objects are made to live, why fossilize them ?
Not to mention, this is also obviously violating 1NF.
As someone suggested, why don't you try MongoDB or other NoSQL database ? Queries are performed using JSON (well, BSON...)

Related

Laravel query where json array of objects contains

I have a mysql table with a JSON column with data looking like that :
"[
{\"messageId\":\"0A0000000123ABCD1\",\"status\":\"request\\/0\",\"messagePrice\":\"0.03330000\"},
{\"messageId\":\"0A0000000123ABCD2\",\"status\":\"request\\/0\",\"messagePrice\":\"0.03330000\"}
]"
How can I query the database to get the row containing a specific messageId (messageIds are uniques) ?
I tried :
DB::table('my_table')
->whereJsonContains('my_json_column',[['messageId'=>'0A0000000123ABCD1']]);
But I get no results.
Edit :
I can make it work with a simple where like :
DB::table('notification_history')
->where('nexmo_responses','like','%0A0000000123ABCD1%')
->get();
But it's not really a clean way to do it.
Your data looks like it's been double-encoded when it was inserted. That's the root of your issue.
If you ensure the data is only encoded once, then it'll be readable correctly when you want to access it again.

Search LIKE json object in mysql

Suppose in my sample_table exist field json_field (stringified JSON object, has property_1, property_2)
How can i select like this request: WHERE property_1 LIKE %VALUE_1% AND property_2 LIKE %VALUE_2% without fetching all data and search with php?
P.S. Yes i know, that was mistake to keep json string in field
You can't.
If you want to get data in your script you have to fetch them. Building dynamic request with the arguments.
Something like :
"...WHERE property_1 LIKE '".$value_1."' AND property_2 LIKE '".$value_2.'";
Not familiar with php, however a decent database interface should allow u to execute any select statement. So according to https://dev.mysql.com/doc/refman/8.0/en/create-table-secondary-indexes.html#json-column-indirect-index you should be able to query based on properties inside a JSON type column.
Even using where col->"$.propertyName" = xxx would work.
Using like 'xxx%' prefix search doesn't seem to work correctly though.
But with the page linked above. You should be able to create a generated column on frequently searched field and create index based on it and search like regular column.
basically JSON_EXTRACT() + LIKE + quote() (if you're using PDO) or real_escape_string() (if you're using mysqli)
$db->query("SELECT * FROM sample_table WHERE
JSON_EXTRACT(`json_field`, '$.property_1') LIKE "
. $db->quote("%{$VALUE_1}%").
" AND JSON_EXTRACT(`json_field`, '$.property_2') LIKE "
. $db->quote("%{$VALUE_2}%")

Creating an 'IF' statement for datatypes in PHP

I'm kind of new to all of this and was hoping I could get some help. Some background that leads to my question is that I am building a small php interface that outputs a table. That table gets values from SQL Server. I have to display 4 tables. 3/4 table display successfully and dynamically (where if the a column or row is added on the SQL server side it will update the php interface tables automatically). The 4th table is giving me an issue. I've at least identified why it breaks the job; the reason is because two columns in the table are 'date_time' values in comparison to varchar or nvarchar values.
Essentially, the way i have it framed up in my head is to create an 'IF' statement in my 'for_loop' that will read the data type of each column, and IF it is a date_time type it will put it in the correct PHP date format, and if not it will put it in the regular format. (this maintains dynamics within the interface, i've done it all successfully, by hard coding the columns, but i'm trying to make my interface 'future-proof')
this is what i had in mind for an if statement:
let's say $field is equivalent to the columns data/value/datatype. This is the variable i use to echo the data from sql server.
$field = sqlsrv_get_field($result, $i);
if(gettype($field) == DateTime)
{
echo "<td>".date_format($field, 'Y-m-d H:i:s')."</td>";
}
else
{
echo "<td>".$field."</td>";
}
I've tried it and it doesn't work. Any suggestions would be helpful, and please keep in mind I am a rookie, so if you could simplify as much as possible that would be greatly appreciated! :)
Thanks again for taking the time to read this, and if you need more information from me, let me know.
Kazmi
1: gettype() returns only the following datatype strings: "boolean", "integer", "double", "string", "array", "object", "resource", "NULL", "unknown type" (source: http://php.net/manual/en/function.gettype.php)
2: Querying a MySQL database in PHP returns always strings, so even if the gettype function would know about "DateTime" it just would return "string".
You can try with this one instead gettype
mysql_field_type(data,field_offset)
and use quotes in if condition
have a look here for details http://php.net/manual/en/function.mysql-field-type.php
For mssql you can use mssql_field_type
have a look here for details http://php.net/manual/en/function.mssql-field-type.php
Thanks to edittor's link, i dug a little further and found a solution. For anyone else who runs into a similar problem, converting dates into string works best, at least for my use case.
here's my code:
$serverName = server
$connectionInfo = array("Database"=>:"enter db", "UID"=>"user", "PWD"=>"password", 'ReturnDatesAsStrings'=> true, "CharacterSet" => 'utf-8');
$con = sqlsrv_connect( $serverName, $connectionInfo);
^^^Returndatesasstrings should be included in your connect statement, from my understanding when it connects to your sql server database and pulls the information.schema it reads which column is 'datetime,date,time,timestamp,etc.' and converts into a string rather then a data value.
Hopefully this helps someone else. Also i find it odd that there isn't much on MSSQL in comparison to MYSQL on this website.

Merging several MySQL results into a single JSON encode (PHP)

Here is code as exists now:
while($row=mysql_fetch_assoc($count_query_result))
$output[]=$row;
while($row=mysql_fetch_assoc($average_query_result))
$output2[]=$row;
while($row=mysql_fetch_assoc($items_query_result))
$output3[]=$row;
print(json_encode(array($output,$output2,$output3)));
mysql_close();
My question:
How do I take a single column from each of the three query results, and make a JSON array out of it, like so:
[{ 'att1' : 'data'}, { 'att2' : 'data'}, { 'att3' : 'data'}]
ASSUMING:
att1 came from the $count_query_result/$output
att2 came from the $average_query_result/$output2
att3 came from the $items_query_result/$output3
Therefore, encoding only one variable, not 3.
Well I answered my own issue. I had to get to the very root of the problem. The MySQL queries. I have joined them all so now there is just one. This creates a single JSON array for what I need. I believe there is something to be said about just doing it ... right .. the first time.
$result = array('att1' => $row['data'],
'att2' => $row['data']
echo json_encode($result)
where $row['data'] is the information that you want returned from each of your queries

Unserialize values from mySQL

I am using a classified scripts and saves user_meta data in the wp_usermeta table.
The meta_key field is called user_address_info and in it there are all the data like below :
s:204:"a:7:{s:9:"user_add1";s:10:"my address";s:9:"user_add2";N;s:9:"user_city";s:7:"my city";s:10:"user_state";s:8:"my phone";s:12:"user_country";N;s:15:"user_postalcode";s:10:"comp phone";s:10:"user_phone";N;}";
I am not using all the fields on the script but user_add1, user_city, user_state and user_postalcode
I am having trouble to get the data using SQL like the example below (wordpress) :
$mylink = $wpdb->get_row("SELECT * FROM $wpdb->links WHERE link_id = 10", ARRAY_A);
I would like some help here so that I will display anywhere (I dont mind using any kind of SQL queries) the requested info e.g. the user_city of current author ID (e.g. 25)
I was given the following example but I want something dynamic
<?php
$s = 's:204:"a:7:{s:9:"user_add1";s:10:"my address";s:9:"user_add2";N;s:9:"user_city";s:7:"my city";s:10:"user_state";s:8:"my phone";s:12:"user_country";N;s:15:"user_postalcode";s:10:"comp phone";s:10:"user_phone";N;}"';
$u = unserialize($s);
$u2 = unserialize($u);
foreach ($u2 as $key => $value) {
echo "<br />$key == $value";
}
?>
Thank you very much.
No, you can't use SQL to unserialize.
That's why storing serialized data in a database is a very bad idea
And twice as bad is doing serialize twice.
So, you've got nothing but use the code you've given.
I see not much static in it though.
do you experience any certain problem with it?
Or you just want to fix something but don't know what something to fix? Get rid of serialization then
i have found that the serialize value stored to database is converted to some other way format. Since the serialize data store quotes marks, semicolon, culry bracket, the mysql need to be save on its own, So it automatically putting "backslash()" that comes from gpc_magic_quotes (CMIIW). So if you store a serialize data and you wanted to used it, in the interface you should used html_entity_decode() to make sure you have the actual format read by PHP.
here was my sample:
$ser = $data->serialization; // assume it is the serialization data from database
$arr_ser = unserialize(html_entity_decode($ser));
nb : i've try it and it works and be sure avoid this type to be stored in tables (to risky). this way can solve the json format stored in table too.

Categories