我想将MySQL存储过程的结果转换为JSON数据并插入到另一个表中。
尝试varchar数据类型时工作正常,但我需要JSON或数组类型的数据。
call="CALL status(input1,@data1,@data2,@data3.......)
select="select @data1, @data2, @data3.....;"
output=$(mysql --user=root --password=xxx db << eof
$call
$select
eof)
mysql --user=root --password=xxx db << eof
insert into sam values ('$output');
eof
这是输出结果,但我需要像JSON这样的输出。如何构造为JSON并将值传递给MySQL中的插入查询。
@data1 @data2 @data3 @data4 @data5 @data6 ..................
1213 1174 367 57 8 7398 39 .............
这是我的存储过程:
DELIMITER ;;
CREATE PROCEDURE status(
IN input1 INT,
IN input2 INT,
OUT data1 INT,
OUT data2 INT,
OUT data3 INT)
BEGIN
-- data1
select count(*) INTO data1 from account where time >=input1 and time >=input2;
-- data2
SELECT SUM(if(status>0,1,0)) INTO data2 from account where time >=input1 and time >=input2;
-- data3
SELECT SUM(if(status=0,1,0)) INTO data3 from account where time >=input1 and time >=input2;
END
;;
如何构建像JSON这样的输出?我是这个话题的新手!!
答案 0 :(得分:1)
MySQL 5.7.8或更高版本支持JSON data type。
从MySQL 5.7.8开始,MySQL支持本机JSON数据类型
如果是这种情况,那么您可以重写存储过程以直接输出所需的JSON
数据。
示例数据
SET @data1 = 1213;
SET @data2 = 1174;
SET @data3 = 367;
SET @data4 = 57;
SET @data5 = 8;
SET @data6 = 7398;
示例SELECT
SELECT JSON_MERGE(
JSON_OBJECT('@data1', @data1),
JSON_OBJECT('@data2', @data2),
JSON_OBJECT('@data3', @data3),
JSON_OBJECT('@data4', @data4),
JSON_OBJECT('@data5', @data5),
JSON_OBJECT('@data6', @data6)
);
输出 (为了更好的可读性而打印漂亮)
{
"@data1": 1213,
"@data2": 1174,
"@data3": 367,
"@data4": 57,
"@data5": 8,
"@data6": 7398
}
然后,为了获得MySQL JSON处理功能,目标列应该具有JSON数据类型。像这样你就可以在mysql中查询你的json。
<强> 击 强>
如果您没有权限重写存储过程,则可以使用以下脏解决方案。只需将mysql的输出管道(|
)输入awk(例如),我们为所需的字段应用必要的格式。为此目的而设计的工具会做得更好,例如:jo或jq。
mysql --login-path=local -s -e 'SET @data1 = 1213; SET @data2 = 1174; SET @data3 = 367; SET @data4 = 57; SET @data5 = 8; SET @data6 = 7398; SELECT @data1, @data2, @data3, @data4, @data5, @data6' | awk '{ print "{\"@data1\":"$1",", "\"@data2\":"$2",", "\"@data3\":"$3",", "\"@data4\":"$4",", "\"@data5\":"$5",", "\"@data6\":"$6"}"}'
请注意我用于mysql身份验证的--login-path=local
而不是-u ... -p...
(Read more here)。
更新 (仅适用于MySQL 5.7.8或更新版本)
我会改写你的存储过程:
DROP PROCEDURE IF EXISTS status_json;
DELIMITER @@
CREATE PROCEDURE status_json (
IN input1 INT,
IN input2 INT,
OUT data JSON
)
proc: BEGIN
SELECT JSON_MERGE(
JSON_OBJECT('count', (SELECT COUNT(*) FROM account WHERE time >= input1 AND time >= input2)),
JSON_OBJECT('sum_gt_0', (SELECT SUM(IF(status > 0, 1, 0)) FROM account WHERE time >= input1 AND time >= input2)),
JSON_OBJECT('sum_eq_0', (SELECT SUM(IF(status = 0, 1, 0)) FROM account WHERE time >= input1 AND time >= input2))
) INTO data;
END proc @@
DELIMITER ;
称之为:
CALL status_json(123, 456, @json);
并使用ouptut:
SELECT @json;
重写存储过程的示例
<强> 表 强>:
CREATE TABLE account (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
time INT UNSIGNED NOT NULL,
status TINYINT UNSIGNED NOT NULL
);
<强> 数据 强>:
INSERT INTO account (time, status) VALUES
(1513329548, 0),
(1513329528, 1),
(1513329508, 1),
(1513329648, 0),
(1513329148, 1),
(1513329540, 0),
(1513322548, 0),
(1513327548, 1);
CALL和SELECT :
CALL status_json(1513329508, 1513322548, @json);
SELECT @json;
<强> 结果 强>:
{"count": 5, "sum_eq_0": 3, "sum_gt_0": 2}