В SQLite, json_extract()
функцията извлича и връща една или повече стойности от добре оформен JSON.
Ние предаваме JSON като аргумент, когато извикаме функцията, и тя връща приложимата стойност/и.
Можем да посочим един или повече пътища за извличане от JSON документа.
Синтаксис
Синтаксисът е така:
json_extract(X,P1,P2,...)
Където X
представлява JSON документа и P1,P2,...
са пътища, които можем да използваме за извличане на определени части от JSON документа.
Примери
Ето основен пример за демонстрация:
SELECT json_extract('{ "a" : 1 }', '$');
Резултат:
{"a":1}
Тук посочих път на $
, който връща целия JSON документ.
Ето пример с по-голям JSON документ:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$'
);
Резултат:
{"dogs":[{"name":"Wag","scores":[7,9]},{"name":"Bark","scores":[3,4,8,7]},{"name":"Woof","scores":[3,2,1]}]}
Нека променим пътя, така че да върнем само dogs
масив:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs'
);
Резултат:
[{"name":"Wag","scores":[7,9]},{"name":"Bark","scores":[3,4,8,7]},{"name":"Woof","scores":[3,2,1]}]
Нека изберем един от елементите в масива:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[1]'
);
Резултат:
{"name":"Bark","scores":[3,4,8,7]}
Масивите са базирани на нула и така броят започва от 0
. Затова посочихме [1]
за да получите втория елемент в dogs
масив, който се оказва JSON обект.
Да отидем отново по-дълбоко и да върнем само името на кучето на тази позиция в масива:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[1].name'
);
Резултат:
Bark
Посочете множество пътища
json_extract()
функцията ни позволява да изберем няколко пътя:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.dogs[0].name',
'$.dogs[1].name',
'$.dogs[2].name'
);
Резултат:
["Wag","Bark","Woof"]
В този случай върнах имената на всички кучета в dogs
масив.
Всички имена на кучета се връщат в масив.
Избиране на несъществуващ път
Ако посочим път, който не съществува, null
се връща.
Първо, нека зададем .nullvalue
до NULL
:
.nullvalue NULL
.nullvalue
командата dot ни позволява да предоставим низ, който ще се използва за замяна на нулеви стойности. Това е един от няколкото начина, по които можете да замените нулеви стойности с низ в SQLite. В този случай го зададох на NULL
. Сега всички нулеви стойности ще върнат NULL
вместо празен резултат.
Сега нека извикаме json_extract()
, но използвайте втори аргумент, който сочи към несъществуващ път:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'$.cats'
);
Резултат:
NULL
Невалидни пътища
Ще получим грешка, ако пътят ни не е добре оформен:
SELECT json_extract('{
"dogs" : [
{ "name" : "Wag", "scores" : [ 7, 9 ] },
{ "name" : "Bark", "scores" : [ 3, 4, 8, 7 ] },
{ "name" : "Woof", "scores" : [ 3, 2, 1 ] }
]
}',
'dogs'
);
Резултат:
Runtime error: JSON path error near 'dogs'
В този случай забравих да включа $.
в предната част на пътеката.
Невалидни JSON документи
Ще получим и грешка, че JSON не е добре оформен:
SELECT json_extract('{ "Dogs" : }',
'$'
);
Резултат:
Runtime error: malformed JSON
Този път грешката ни казва, че нашият JSON е неправилно оформен.
Типове връщане
Документацията на SQLite гласи следното:
Ако е предоставен само един път P1, тогава SQL типът данни на резултата е NULL за нула JSON, INTEGER или REAL за числова стойност в JSON, INTEGER нула за фалшива стойност в JSON, INTEGER единица за истинска стойност в JSON, децитираният текст за стойност на низ JSON и текстово представяне за стойности на JSON обект и масив. Ако има множество аргументи на пътя (P1, P2 и т.н.), тогава тази процедура връща текст на SQLite, който е добре оформен JSON масив, съдържащ различните стойности.
Съвместимост с MySQL
Документацията на SQLite също ни предупреждава за фина несъвместимост между реализациите на SQLite и MySQL на json_extract()
функция.
По-конкретно, той гласи:
MySQL версията на json_extract() винаги връща JSON. Версията на SQLite на json_extract() връща JSON само ако има два или повече аргумента PATH (защото резултатът е JSON масив) или ако единичният аргумент PATH препраща към масив или обект. В SQLite, ако json_extract() има само един аргумент PATH и този PATH препраща към JSON null или низ или числова стойност, тогава json_extract() връща съответната стойност NULL, TEXT, INTEGER или REAL.
По принцип тази разлика става очевидна само при достъп до отделни стойности в JSON, които са низове или NULL.