Reputation: 859
The project I'm working on requires to save all of the DB operations. So when there will be added new user I've to log the date, operation type like 'INSERT', 'UPDATE', 'DELETE' and all user data. The project is in the development phase so the columns in User table are changing.
This what I plan to do is to select the new user data from the Users table and insert them to UserLog table as a JSON column.
Is it possible to convert SELECT * FROM table_name
to JSON format?
I know that there is a possibility to convert separated columns by JSON_OBJECT function, but as I mentioned above, the columns are floating so I would be forced to change the JSON_OBJECT names each time I change anything in the main table. And there are a lot of tables!
It should work like this:
CREATE TABLE Users (
id INT(1) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstName VARCHAR(30) NOT NULL,
lastName VARCHAR(30) NOT NULL,
email VARCHAR(50),
)
The query:
SELECT * FROM Users;
Should return:
[
{
"id": 1,
"firstName": "Lucas",
"lastName": "Smith",
"email": "[email protected]"
},
{
"id": 2,
"firstName": "Ben",
"lastName": "Kovalsky",
"email": "[email protected]"
},
...
]
Is there a simple solution to solve this problem? If not, what is your strategy for logging DB operations?
Upvotes: 4
Views: 10859
Reputation: 179
I know this is an old thread, but for anyone still facing this issue, there is a way to convert the result set into json without knowing the column names. The key is to get the names of the columns in a string like 'column_1', column_1, 'column_2', column_2, ...
and then use this string in a prepared query.
SET @column_name_string_for_query = "";
SHOW COLUMNS
FROM your_table_name
WHERE @column_name_string_for_query := TRIM(", " FROM CONCAT("'", Field, "', ", Field, ", ", @column_name_string_for_query));
SET @query_string = concat("
SELECT JSON_ARRAYAGG(JSON_OBJECT(", @column_name_string_for_query, "))
FROM your_table_name"
);
PREPARE statement FROM @query_string;
EXECUTE statement;
DEALLOCATE PREPARE statement;
You could also get the column names from INFORMATION_SCHEMA.COLUMNS
, but that only works for tables that are not temporary tables. The solution above works for both temporary tables and normal tables.
You could also save this as a stored procedure for ease of use.
Upvotes: 2
Reputation: 27856
Normally converting the output to JSON or any other format is a job for the programming language or your mySQL IDE, but there is a way also from mySQL.
https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-json-output.html
https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-json-wrapping.html
Directly from documentation:
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','json')
MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'")
{
"ID": 1523,
"Name": "Wien",
"CountryCode": "AUT",
"District": "Wien",
"Info": {
"Population": 1608144
}
}
{
"ID": 1524,
"Name": "Graz",
"CountryCode": "AUT",
"District": "Steiermark",
"Info": {
"Population": 240967
}
}
{
"ID": 1525,
"Name": "Linz",
"CountryCode": "AUT",
"District": "North Austria",
"Info": {
"Population": 188022
}
}
{
"ID": 1526,
"Name": "Salzburg",
"CountryCode": "AUT",
"District": "Salzburg",
"Info": {
"Population": 144247
}
}
{
"ID": 1527,
"Name": "Innsbruck",
"CountryCode": "AUT",
"District": "Tiroli",
"Info": {
"Population": 111752
}
}
{
"ID": 1528,
"Name": "Klagenfurt",
"CountryCode": "AUT",
"District": "Kärnten",
"Info": {
"Population": 91141
}
}
6 rows in set (0.0031 sec)
Also, adding the JSON_OBJECT, that is available from 5.7+, see the answer here.
mysql> SELECT JSON_OBJECT('id', 87, 'name', 'carrot');
+-----------------------------------------+
| JSON_OBJECT('id', 87, 'name', 'carrot') |
+-----------------------------------------+
| {"id": 87, "name": "carrot"} |
+-----------------------------------------
Upvotes: 0
Reputation: 69
I'm not up to date with MySQL as I switched over to PostgreSQL but I found that the recent MySQL, from version 8, supports JSON:
SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'id', `id`,
'firstName', `firstName`,
'lastName', `lastName`,
'email', `email`
)
)
FROM Users;
should work.
Edit, sources:
Upvotes: 3