Как преобразовать результат хранимой процедуры MySQL в данные JSON в сценарии оболочки?

0

Я хотел бы преобразовать результат хранимой процедуры MySQL в данные JSON и вставить в другую таблицу.

При попытке varchar datatype работать нормально, но мне нужны данные 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? Я новичок в этой теме !!

Теги:
stored-procedures

1 ответ

1
Лучший ответ

MySQL 5.7.8 или более поздние версии поддерживают тип данных JSON.

Начиная с 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
}

Затем, чтобы воспользоваться возможностями обработки JSON MySQL, столбец назначения должен иметь тип данных JSON. Как и вы, вы сможете запросить свой json в mysql.

удар

Если вы не имеете права переписывать хранимую процедуру, вы можете использовать следующее грязное решение. Просто pipe (|) вывод 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"}"}'

Обратите внимание на --login-path=local который я использую для проверки подлинности mysql вместо -u... -p... (Подробнее читайте здесь).

UPDATE (работает только с 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}
  • 0
    спасибо @marcell, я новичок в этой теме и запутался в заданном значении. Я добавил свою хранимую процедуру выше, пожалуйста, дайте краткое описание, чтобы решить эту проблему.
  • 0
    В моем примере я просто быстро симулирую данные. Для этого я использовал SET , чтобы присвоить значения переменным и использовать их позже.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню