第六十九章 SQL函数 JSON_OBJECT
将数据作为JSON 对象返回的转换函数。
大纲
JSON_OBJECT(key:value [,key:value][,...] [NULL ON NULL | ABSENT ON NULL])
参数
key:value - 键:值对或逗号分隔的键:值对列表。键是由单引号分隔的用户指定的文字字符串。值可以是列名、聚合函数、算术表达式、数字或字符串文字或文字NULL 。ABSENT ON NULL NULL ON NULL - 可选-指定如何在返回的JSON 对象中表示空值的关键字短语。NULL ON NULL (缺省值)表示带有单词NULL (未引号)的NULL (缺少)数据。在NULL 上缺失将从JSON 对象中省略NULL 数据;当value 为NULL 且不保留占位符逗号时,它将删除key:value 对。此关键字短语对空字符串值没有影响。
描述
JSON_OBJECT 接受逗号分隔的键:值对列表(例如,‘MyKey’:colname ),并返回包含这些值的JSON对象。可以指定任何单引号字符串作为键名;JSON_OBJECT 不强制任何命名约定或对键名进行唯一性检查。可以为值指定列名或其他表达式。
JSON_OBJECT 可以在SELECT 语句中与其他类型的SELECT-Items 结合使用。可以在可以使用SQL函数的其他位置指定JSON_OBJECT ,例如在WHERE 子句中。
返回的JSON 对象格式如下:
{ "key1" : "value1" , "key2" : "value2" , "key3" : "value3" }
Json_object 以字符串(用双引号括起来)或数字形式返回对象值。数字以规范格式返回。数字字符串以文字形式返回,用双引号括起来。所有其他数据类型(例如,DATE 或$LIST )都以字符串形式返回,当前的%SelectMode 决定返回值的格式。Json_object 以显示或ODBC模式返回键和值值(如果这是查询的选择模式)。
JSON_OBJECT 不支持将星号(* )语法作为指定表中所有字段的方式。
返回的JSON 对象列被标记为表达式(默认情况下);可以为JSON_OBJECT 指定列别名。
选择模式和排序
当前%SelectMode 属性确定返回的JSON 对象值的格式。通过更改选择模式,所有日期和%LIST 值都会以该选择模式格式的字符串形式包含在JSON 对象中。可以通过将格式转换函数(%EXTERNAL 、%INTERNAL 、%ODBCIN 、%ODBCOUT )应用于JSON_OBJECT 中的各个字段名来覆盖当前的选择模式。将格式转换函数应用于JSON_OBJECT 没有任何效果,因为JSON 对象的键:值对是字符串。
默认排序规则确定返回的JSON 对象值的排序规则。可以将排序函数应用于JSON_OBJECT ,同时转换键和值。通常,不应该对JSON_OBJECT 应用排序函数,因为键区分大小写。在JSON 对象格式化之后应用排序规则。因此,%SQLUPPER(JSON_OBJECT(‘K1’:F1,‘K2’:F2)) 将所有JSON 对象键和值字符串转换为大写。%SQLUPPER 在JSON对象之前插入一个空格,而不是在对象内的值之前。
在JSON_OBJECT 中,可以将排序函数应用于键:值对的值部分。由于%SQLUPPER 会在值之前插入一个空格,因此通常最好指定大小写转换函数,如LCASE 或UCASE 。
ABSENT ON NULL
如果指定可选的ACESING ON NULL 关键字短语,则JSON 对象中不包括NULL (或NULL 文字)列值。JSON 对象中不包括占位符。这可能会导致JSON 对象具有不同数量的键:值对。例如,下面的程序返回JSON 对象,其中对于某些记录,第三个键:值对是Age ,对于其他记录,第三个键:值对是FavoriteColors :
SELECT JSON_OBJECT('id':%ID,'name':Name,'colors':FavoriteColors,'years':Age ABSENT ON NULL) FROM Sample.Person
如果未指定关键字短语,则NULL 的默认值为NULL:NULL 由单词NULL (未用引号分隔)表示,作为key:value 对的值。因此,JSON_OBJECT 函数返回的所有JSON 对象将具有相同数量的键:值对。
示例
下面的动态SQL示例应用JSON_OBJECT 来格式化包含字段值的JSON 对象:
ClassMethod JsonObject()
{
s myquery = 2
s myquery(1) = "SELECT TOP 3 JSON_OBJECT('id':%ID,'name':Name,'birth':DOB,"
s myquery(2) = "'age':Age,'state':Home_State) FROM Sample.Person"
s tStatement = ##class(%SQL.Statement).%New()
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
while rset.%Next() {DO rset.%Print(" ^ ")}
w !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).JsonObject()
{"id":1,"name":"yaoxin","birth":54536,"age":31,"state":"WI"}
{"id":2,"name":"xiaoli","birth":null,"age":null,"state":null}
{"id":6,"name":"姚鑫","birth":63189,"age":8,"state":null}
Total row count=3
下面的动态SQL示例应用JSON_OBJECT 来格式化包含文字和字段值的JSON 对象:
ClassMethod JsonObject1()
{
s myquery = 2
s myquery(1) = "SELECT TOP 3 JSON_OBJECT('lit':'Employee from','t':%TABLENAME,"
s myquery(2) = "'name':Name,'num':SSN) FROM Sample.Employee"
s tStatement = ##class(%SQL.Statement).%New()
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
while rset.%Next() {DO rset.%Print(" ^ ")}
w !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).JsonObject1()
{"lit":"Employee from","t":"Sample.Employee","name":"xiaoli","num":"111-11-1111"}
{"lit":"Employee from","t":"Sample.Employee","name":"Chadwick,Phyllis L.","num":"852-26-8969"}
{"lit":"Employee from","t":"Sample.Employee","name":"Schaefer,Usha G.","num":"488-63-3164"}
Total row count=3
下面的动态SQL示例应用JSON_OBJECT 来格式化包含空值和字段值的JSON 对象:
ClassMethod JsonObject2()
{
s myquery = 2
s myquery(1) = "SELECT JSON_OBJECT('name':Name,'colors':FavoriteColors) FROM Sample.Person"
s myquery(2) = " WHERE Name %STARTSWITH 'S'"
s tStatement = ##class(%SQL.Statement).%New()
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
while rset.%Next() {DO rset.%Print(" ^ ")}
w !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).JsonObject2()
{"name":"Smith,Kyra P.","colors":"\b\u0001Yellow"}
{"name":"Smith,Elvis Y.","colors":"\b\u0001Orange\b\u0001Orange"}
{"name":"Solomon,Emily D.","colors":null}
{"name":"Schaefer,Usha G.","colors":"\b\u0001Orange\u0007\u0001White"}
{"name":"Sorenson,Samantha X.","colors":"\u0007\u0001White\b\u0001Orange"}
{"name":"Schaefer,Jocelyn V.","colors":"\b\u0001Yellow"}
Total row count=6
下面的动态SQL示例设置ODBC %SelectMode ,它确定如何表示所有字段,包括JSON 对象值。该查询通过应用%EXTERNAL FORMAT-CONFORMAT 函数覆盖特定JSON_OBJECT 值的此选择模式:
ClassMethod JsonObject3()
{
s myquery = 3
s myquery(1) = "SELECT TOP 8 JSON_OBJECT('ODBCBday':DOB,'DispBday':%EXTERNAL(DOB)),"
s myquery(2) = "JSON_OBJECT('ODBCcolors':FavoriteColors,'DispColors':%EXTERNAL(FavoriteColors)) "
s myquery(3) = "FROM Sample.Person"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
w "SelectMode is ODBC",!
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
if rset.%SQLCODE=0 { w !,"Executed query",! }
else { s badSQL=##class(%Exception.SQL).%New(,rset.%SQLCODE,,rset.%Message)}
d rset.%Display()
w !,"End of data"
}
DHC-APP> d ##class(PHA.TEST.SQLCommand).JsonObject3()
SelectMode is ODBC
Executed query
Expression_1 Expression_2
{"ODBCBday":"1990-04-25","DispBday":"04/25/1990"} {"ODBCcolors":"Red,Orange,Yellow","DispColors":"Red\r\nOrange\r\nYellow"}
{"ODBCBday":null,"DispBday":null} {"ODBCcolors":null,"DispColors":null}
{"ODBCBday":"2014-01-02","DispBday":"01/02/2014"} {"ODBCcolors":null,"DispColors":null}
{"ODBCBday":"2014-01-02","DispBday":"01/02/2014"} {"ODBCcolors":null,"DispColors":null}
{"ODBCBday":"1978-01-28","DispBday":"01/28/1978"} {"ODBCcolors":null,"DispColors":null}
{"ODBCBday":null,"DispBday":null} {"ODBCcolors":"Red,Orange,Yellow,Green","DispColors":"Red\r\nOrange\r\nYellow\r\nGreen"}
{"ODBCBday":null,"DispBday":null} {"ODBCcolors":"Red,Orange,Yellow,Green,Green","DispColors":"Red\r\nOrange\r\nYellow\r\nGreen\r\nGreen"}
{"ODBCBday":null,"DispBday":null} {"ODBCcolors":"Red,Orange,Yellow,Green,Yellow","DispColors":"Red\r\nOrange\r\nYellow\r\nGreen\r\nYellow"}
8 Rows(s) Affected
End of data
下面的动态SQL示例应用JSON_OBJECT 来格式化包含联接表中的字段值的JSON 对象:
ClassMethod JsonObject4()
{
s myquery = 2
s myquery(1) = "SELECT TOP 3 JSON_OBJECT('e.t':E.%TABLENAME,'e.name':E.Name,'c.t':C.%TABLENAME,"
s myquery(2) = "'c.name':C.Name) FROM Sample.Employee AS E,Sample.Company AS C"
s tStatement = ##class(%SQL.Statement).%New()
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
while rset.%Next() {d rset.%Print(" ^ ")}
w !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).JsonObject4()
{"e.t":"Sample.Employee","e.name":"Adams,Susan E.","c.t":"Sample.Company","c.name":"MacroComp Media Inc."}
{"e.t":"Sample.Employee","e.name":"Alton,Phil T.","c.t":"Sample.Company","c.name":"MacroComp Media Inc."}
{"e.t":"Sample.Employee","e.name":"Anderson,Valery N.","c.t":"Sample.Company","c.name":"MacroComp Media Inc."}
Total row count=3
下面的动态SQL示例在WHERE 子句中使用JSON_OBJECT 在不使用OR 语法的情况下对多列执行CONTAINS 测试:
ClassMethod JsonObject5()
{
s myquery = 2
s myquery(1) = "SELECT Name,Home_City,Home_State FROM Sample.Person"
s myquery(2) = " WHERE JSON_OBJECT('name':Name,'city':Home_City,'state':Home_State) [ 'X'"
s tStatement = ##class(%SQL.Statement).%New()
s qStatus = tStatement.%Prepare(.myquery)
s rset = tStatement.%Execute()
while rset.%Next() {d rset.%Print(" ^ ")}
w !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).JsonObject5()
Zevon,Heloisa O. ^ Xavier ^ MI
Bukowski,Mario V. ^ Xavier ^ TX
Pascal,Kim P. ^ Xavier ^ OR
Xerxes,Angelo P. ^ Youngstown ^ AL
Bachman,Susan O. ^ Chicago ^ TX
Russell,Joe M. ^ Xavier ^ VA
Ingrahm,Molly X. ^ Chicago ^ ND
Xavier,Dmitry B. ^ Miami ^ PA
Martinez,Terry T. ^ Xavier ^ CO
Ahmed,Elmo X. ^ Oak Creek ^ AZ
Basile,Filomena X. ^ Denver ^ NJ
Frost,Xavier D. ^ Miami ^ MO
Gore,Fred X. ^ Denver ^ TN
Lepon,Kevin N. ^ Newton ^ TX
Chadwick,Phyllis L. ^ Xavier ^ SC
|