0 关注者 · 478 帖子

SQL 是在关系数据库中存储、操作和检索数据的标准语言。

文章 姚 鑫 · 三月 31, 2022 2m read

第九十八章 SQL函数 MONTHNAME

返回日期表达式的月份名称的日期函数。

大纲

{fn MONTHNAME(date-expression)}

参数

  • date-expression - 计算结果为 日期整数、ODBC 日期或时间戳的表达式。此表达式可以是列名、另一个标量函数的结果或日期或时间戳字面量。

描述

MONTHNAME 将日期整数、$HOROLOG$ZTIMESTAMP 值、ODBC 格式日期字符串或时间戳作为输入。

日期表达式时间戳可以是数据类型 %Library.PosixTime(编码的 64 位有符号整数),也可以是数据类型 %Library.TimeStamp (yyyy-mm-dd hh:mm:ss.fff)

时间戳的时间部分不被评估,可以省略。

MONTHNAME 返回相应日历月的名称,从一月到十二月。返回值是一个字符串,最大长度为 15。

MONTHNAME 检查提供的日期是否有效。年份必须介于 00019999(含)之间、月份 0112 以及适合该月的日期(例如,02/29 仅在闰年有效)。如果日期无效,MONTHNAME 会发出 SQLCODE -400<ILLEGAL VALUE>错误。

月份名称默认为全长美式英语月份名称。要更改这些月份名称值,请使用带有 MONTH_NAME 选项的 SET OPTION 命令。

使用 DATENAME 函数可以返回相同的月份名称信息。可以使用 TO_DATE 检索月份名称或月份名称缩写与其他日期元素。要返回与月份对应的整数,请使用 MONTH DATEPARTTO_DATE

也可以使用 MONTHNAME() 方法调用从 ObjectScript 调用此函数:

$SYSTEM.SQL.Functions.MONTHNAME(date-expression)

示例

以下示例均返回字符串“February”,因为它是日期表达式的月份(2018 年 2 月 22 日):

SELECT {fn MONTHNAME('2018-02-22')} AS NameOfMonth

February
SELECT {fn MONTHNAME(64701)} AS NameOfMonth

February

以下示例均返回当前月份:

SELECT {fn MONTHNAME({fn NOW()})} AS MnameNow,
       {fn MONTHNAME(CURRENT_DATE)} AS MNameCurrDate,
       {fn MONTHNAME(CURRENT_TIMESTAMP)} AS MNameCurrTS,
       {fn MONTHNAME($HOROLOG)} AS MNameHorolog,
       {fn MONTHNAME($ZTIMESTAMP)} AS MNameZTS
       
March	March	March	March	March

以下嵌入式 SQL 示例显示了 MONTHNAME 如何响应无效日期(2017 年不是闰年):

/// d ##class(PHA.TEST.SQLFunction).MonthName()
ClassMethod MonthName()
{
	s testdate = "2017-02-29"
	&sql(
		SELECT {fn MONTHNAME(:testdate)} INTO :a
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE,!
		w %msg,! 
	} else {	
		w !,"returns: ",a 
	}
	q
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).MonthName()
 
Error code -400
Unexpected error occurred:  <ILLEGAL VALUE>%0BCo+10^PHA.TEST.SQLFunction.1
 

SQLCODE -400 错误代码与指示 <ILLEGAL VALUE>%msg 一起发出。

0
0 54
文章 姚 鑫 · 三月 30, 2022 2m read

第九十七章 SQL函数 MONTH

日期函数,它将月份作为日期表达式的整数返回。

大纲

MONTH(date-expression)

{fn MONTH(date-expression)}

描述

  • date-expression - 表达式,它是列的名称、另一个标量函数的结果,或者是日期或时间戳文字。

描述

MONTH 返回一个指定月份的整数。月份整数是针对 日期整数、$HOROLOG$ZTIMESTAMP 值、ODBC 格式日期字符串或时间戳计算的。

日期表达式时间戳可以是数据类型 %Library.PosixTime(编码的 64 位有符号整数),也可以是数据类型 %Library.TimeStamp (yyyy-mm-dd hh:mm:ss.fff)。

日期字符串的月份 (mm) 部分必须是 112 范围内的整数。前导零在输入时是可选的。输出时抑制前导零和尾随零。

date-expression 的日期部分经过验证,并且必须包含 112 范围内的月份以及指定月份和年份的有效日期值。否则,将生成 SQLCODE -400 错误 <ILLEGAL VALUE>

date-expression 的时间部分未经验证,可以省略。

请注意,MONTH 可以作为 ODBC 标量函数(使用大括号语法)或作为 SQL 通用函数调用。

$SYSTEM.SQL.Functions.MONTH(date-expression)

可以使用以下 SQL 函数返回日期时间字符串的元素:YEARMONTHDAY(或 DAYOFMONTH)、HOURMINUTESECOND。使用 DATEPARTDATENAME 函数可以返回相同的元素。可以使用 TO_DATE 返回日期元素。 DATEPARTDATENAME 对月份值执行值和范围检查。

LAST_DAY 函数返回指定月份的最后一天的日期。

示例

以下示例均返回数字 2,因为二月是一年中的第二个月:

SELECT MONTH('2018-02-22') AS Month_Given

2
SELECT {fn MONTH(64701)} AS Month_Given

2

以下示例按生日顺序按月和日对记录进行排序,忽略 DOB 的年份部分:

SELECT Name,DOB AS Birthdays
FROM Sample.Person
ORDER BY MONTH(DOB),DAY(DOB),Name

以下示例均返回当前月份:

SELECT {fn MONTH({fn NOW()})} AS MNow,
       MONTH(CURRENT_DATE) AS MCurrD,
       {fn MONTH(CURRENT_TIMESTAMP)} AS MCurrTS,
       MONTH($HOROLOG) AS MHorolog,
       {fn MONTH($ZTIMESTAMP)} AS MZTS
       
       
3	3	3	3	3
0
0 72
文章 姚 鑫 · 三月 29, 2022 2m read

第九十六章 SQL函数 MOD

注:IRIS可用,非IRIS版本不可用。

标量数值函数,返回一个数除以另一个数的模数(余数)。

大纲

MOD(dividend,divisor)

{fn MOD(dividend,divisor)}

参数

  • dividend - 数字,它是除法的分子(除数)。
  • divisor - 数字,它是除法的分母(除数)。

MOD 返回 NUMERIC 数据类型,除非被除数是数据类型 DOUBLE。如果dividendDOUBLE,则 MOD 返回 DOUBLE

描述

MOD 返回除数除数的数学余数(模数)。

MOD 可以指定为标准标量函数或带有大括号语法的 ODBC 标量函数。

  • 如果被除数和除数为正数,则返回正数模数或零。
  • 如果被除数和除数都是负数,则返回负模数或零。
  • 如果被除数或除数为 NULL,则返回 NULL
  • 如果除数为 0,它将生成带有 %msg<DIVIDE>错误的 SQLCODE -400
  • 如果除数大于被除数,则返回被除数。

MOD(任一语法形式)报告的精度与算术表达式除数/除数的精度报告相同。

ANSI 运算符优先级

具有单个负操作数的 MOD 函数的行为取决于 Apply ANSI Operator Precedence 配置设置:

  • 如果未应用 Apply ANSI Operator Precedence,则带有负操作数的 MOD 的行为与 # 模运算符相同。两者都返回短计数(达到下一个倍数所需的数量),而不是模数。例如,12#7 返回模数 5–12#7 返回短计数 2。如果被除数为负,短计数为正值或零。如果除数为负,则短计数为负值或零。
  • 如果应用了 Apply ANSI Operator Precedence(IRIS 2019.1 及后续版本的默认设置),带有负操作数的 MOD 的行为是始终返回模数。如果被除数为负,则返回负模数或零。如果除数为负,则返回正模数或零。

# modulo operator 的行为不受应用 ANSI 运算符优先级配置设置的影响。

示例

以下示例显示了 MOD 返回的余数。

SELECT MOD(5,3) AS Remainder

2
SELECT MOD(5.3,.5) AS Remainder


0.3
0
0 129
文章 姚 鑫 · 三月 28, 2022 3m read

第九十五章 SQL函数 MINUTE

返回日期时间表达式的分钟的时间函数。

大纲

{fn MINUTE(time-expression)}

参数

  • time-expression - 作为列名、另一个标量函数的结果或字符串或数字文字的表达式。它必须解析为日期时间字符串或时间整数,其中基础数据类型可以表示为 %Time%TimeStamp%PosixTime

描述

MINUTE 返回一个整数,指定给定时间或日期时间值的分钟数。为 $HOROLOG$ZTIMESTAMP 值、ODBC 格式日期字符串或时间戳计算分钟。

时间表达式时间戳可以是数据类型 %Library.PosixTime(编码的 64 位有符号整数),也可以是数据类型 %Library.TimeStamp (yyyy-mm-dd hh:mm:ss.fff)。

要更改默认时间格式,请使用 SET OPTION 命令。

请注意,可以提供时间整数(经过的秒数),但不能提供时间字符串 (hh:mm:ss)。必须提供日期时间字符串 (yyyy-mm-dd hh:mm:ss)。

日期时间字符串的时间部分必须是有效时间。否则,将生成 SQLCODE -400 错误 <ILLEGAL VALUE> 。分钟 (mm) 部分必须是 059 范围内的整数。前导零在输入时是可选的;前导零在输出上被抑制。可以省略日期时间字符串的秒 (:ss) 部分,但仍返回分钟部分。

日期时间字符串的日期部分未经过验证。

当分钟部分为“0”“00”时,MINUTE 返回零分钟。如果没有提供时间表达式,或者完全省略时间表达式的分钟部分('hh', 'hh:', 'hh::', or 'hh::ss'),也会返回零分钟。

可以使用 DATEPARTDATENAME 返回相同的时间信息。

也可以使用 MINUTE() 方法调用从 ObjectScript 调用此函数:

$SYSTEM.SQL.Functions.MINUTE(time-expression)

示例

以下示例都返回数字 45,因为它是 datetime 字符串中时间表达式的第 45 分钟:

SELECT {fn MINUTE('2018-02-16 18:45:38')} AS ODBCMinutes

45
SELECT {fn MINUTE(67538)} AS HorologMinutes

45

以下示例也返回 45。如此处所示,时间值的秒部分可以省略:

SELECT {fn MINUTE('2018-02-16 18:45')} AS Minutes_Given

45

以下示例返回 0 分钟,因为日期时间字符串中省略了时间表达式:

SELECT {fn MINUTE('2018-02-16')} AS Minutes_Given

0

以下示例均返回当前时间的分钟部分:

SELECT {fn MINUTE(CURRENT_TIME)} AS Min_CurrentT,
       {fn MINUTE({fn CURTIME()})} AS Min_CurT,
       {fn MINUTE({fn NOW()})} AS Min_Now,
       {fn MINUTE($HOROLOG)} AS Min_Horolog,
       {fn MINUTE($ZTIMESTAMP)} AS Min_ZTS
       
27	27	27	27	27

以下示例显示前导零被抑制。第一个 MINUTE 函数返回长度为 2,其他函数返回长度为 1。省略的时间被认为是 0 分钟,其长度为 1

SELECT LENGTH({fn MINUTE('2018-02-22 11:45:00')}),
       LENGTH({fn MINUTE('2018-02-22 03:05:00')}),
       LENGTH({fn MINUTE('2018-02-22 3:5:0')}),
       LENGTH({fn MINUTE('2018-02-22')})
       
2	1	1	1

以下嵌入式 SQL 示例显示 MINUTE 函数识别为区域设置指定的 TimeSeparator 字符:

/// d ##class(PHA.TEST.SQLFunction).Minute()
ClassMethod Minute()
{
	d ##class(%SYS.NLS.Format).SetFormatItem("TimeSeparator", ".")
	&sql(
		SELECT {fn MINUTE('2018-02-22 18.45.38')}
			INTO :a)
	w "minutes=",a
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Minute()
minutes=45
0
0 91
文章 姚 鑫 · 三月 27, 2022 2m read

第九十四章 SQL函数 %MINUS

将数字转换为规范整理格式,然后反转符号的整理函数。

大纲

%MINUS(expression)

%MINUS expression

参数

  • expression - 表达式,可以是列名、数字或字符串文字、算术表达式或另一个函数的结果,其中基础数据类型可以表示为任何字符类型。

描述

%MINUS 将数字或数字字符串转换为规范形式,反转符号,然后以数字排序规则返回这些表达式值。

%MINUS%PLUS 在功能上是相同的,只是 %MINUS 反转了符号。它为解析为正数的任何数字添加减号前缀,并从解析为负数的任何数字中删除减号。零从不签名。

一个数字可以包含前导零和尾随零、多个前导加号和减号、一个小数点指示符 (.) 和 E 指数指示符。在规范形式中,执行所有算术运算,扩展指数,将符号解析为单个前导减号或无符号,并去除前导零和尾随零。

可以使用或不使用封闭字符串分隔符来指定数字文字。如果字符串包含非数字字符,%MINUS 会在第一个非数字字符处截断数字,并以规范形式返回数字部分。非数字字符串(任何以非数字字符开头的字符串)返回为 0%MINUS 也将 NULL 作为 0 返回。

%MINUS 是一个 SQL 扩展,用于 SQL 查找查询。

可以使用 %SYSTEM.Util 类的 Collation() 方法在 ObjectScript 中执行相同的排序规则转换:

DHC-APP>  WRITE $SYSTEM.Util.Collation("++007.500",4)
-7.5

%MINUS%MVR 排序规则进行比较,后者根据字符串中的数字子字符串对字符串进行排序。

示例

以下示例使用 %MINUS 以家庭街道号的数字降序返回记录:

SELECT Name,Home_Street
FROM Sample.Person
ORDER BY %MINUS(Home_Street)

image

请注意,上面的示例按数字顺序对街道地址的整数部分进行排序。将此与以下 ORDER BY DESC 示例进行比较,该示例按整理顺序中的街道地址对记录进行排序:

SELECT Name,Home_Street
FROM Sample.Person
ORDER BY Home_Street DESC

image

0
0 78
文章 姚 鑫 · 三月 26, 2022 2m read

第九十三章 SQL函数 LTRIM

字符串函数,它返回一个删除了前导空格的字符串。

大纲

LTRIM(string-expression)

{fn LTRIM(string-expression)}

参数

  • string-expression - 字符串表达式,可以是列名、字符串文字或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(例如 CHARVARCHAR)。

描述

LTRIM 从字符串表达式中删除前导空格,并将字符串作为 VARCHAR 类型返回。如果 string-expressionNULL,则 LTRIM 返回 NULL。如果 string-expression 是一个完全由空格组成的字符串,则 LTRIM 返回空字符串 ('')

LTRIM 留下尾随空格;要删除尾随空格,请使用 RTRIM。要删除任何类型的前导和/或尾随字符,请使用 TRIM。要使用前导空格或其他字符填充字符串,请使用 LPAD。要创建一串空白,请使用 SPACE

请注意,LTRIM 可用作 ODBC 标量函数(使用大括号语法)或 SQL 通用函数。

示例

以下嵌入式 SQL 示例从字符串中删除了五个前导空格。它留下五个尾随空白:

ClassMethod Ltrim()
{
	s a = "     Test string with 5 leading and 5 trailing spaces.     "
	&sql(
		SELECT {fn LTRIM(:a)} INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"Before LTRIM",!,"start:",a,":end"
		w !,"After LTRIM",!,"start:",b,":end" 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Ltrim()
 
Before LTRIM
start:     Test string with 5 leading and 5 trailing spaces.     :end
After LTRIM
start:Test string with 5 leading and 5 trailing spaces.     :end
0
0 72
文章 姚 鑫 · 三月 25, 2022 2m read

[toc]

第九十二章 SQL函数 LPAD

字符串函数,它返回一个左填充到指定长度的字符串。

大纲

LPAD(string-expression,length[,padstring])

参数

  • string-expression - 字符串表达式,可以是列名、字符串文字、主机变量或另一个标量函数的结果。可以是可转换为 VARCHAR 数据类型的任何数据类型。字符串表达式不能是流。
  • length - 一个整数,指定返回的字符串中的字符数。
  • padstring - 可选 — 由一个字符或一串字符组成的字符串,用于填充输入字符串表达式。 padstring 字符或字符附加到 string-expression 的左侧,以提供创建长度字符的输出字符串所需的尽可能多的字符。 padstring 可以是字符串文字、列、主机变量或另一个标量函数的结果。如果省略,则默认为空格字符。

描述

LPAD 用前导填充字符填充字符串表达式。它返回填充到长度字符数的字符串的副本。如果字符串表达式的长度超过 length 个字符,则返回字符串被截断为 length 个字符。

如果 string-expressionNULL,则 LPAD 返回 NULL。如果 string-expression 是空字符串('') LPAD 返回一个完全由填充字符组成的字符串。返回的字符串是 VARCHAR 类型。

LPAD 可用于针对链接表的查询。

LPAD 不会删除前导或尾随空格;它填充字符串,包括任何前导或尾随空格。要在填充字符串之前删除前导或尾随空格,请使用 LTRIMRTRIMTRIM

LPAD 和 $JUSTIFY

LPAD 的双参数形式和 $JUSTIFY 的双参数形式都通过用前导空格填充字符串来右对齐字符串。这两个参数形式的不同之处在于它们如何处理比输入字符串表达式的长度短的输出长度:LPAD 截断输入字符串以适应指定的输出长度。 $JUSTIFY 扩展输出长度以适应输入字符串。这在以下示例中显示:

SELECT '>'||LPAD(12345,10)||'<' AS lpadplus,
       '>'||$JUSTIFY(12345,10)||'<' AS justifyplus,
       '>'||LPAD(12345,3)||'<' AS lpadminus,
       '>'||$JUSTIFY(12345,3)||'<' AS justifyminus

示例

以下示例用 ^ 字符(在需要时)左填充列值以返回长度为 16 的字符串。请注意,一些名称字符串被左填充,一些名称字符串被右截断以返回长度为 16 的字符串。

SELECT TOP 15 Name,LPAD(Name,16,'^') AS Name16
   FROM Sample.Person 

以下示例使用 ^=^ 填充字符串(在需要时)填充列值以返回长度为 20 的字符串。请注意,填充名称字符串根据需要重复多次,并且一些返回字符串包含部分填充字符串:

SELECT TOP 15 Name,LPAD(Name,20,'^=^') AS Name20
   FROM Sample.Person 
0
0 100
文章 姚 鑫 · 三月 24, 2022 2m read

第九十一章 SQL函数 LOWER

将字符串表达式中的所有大写字母转换为小写字母的大小写转换函数。

大纲

LOWER(string-expression)

参数

  • string-expression - 要将其字符转换为小写的字符串表达式。表达式可以是列名、字符串文字或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(例如 CHARVARCHAR)。

描述

LOWER 函数将大写字母转换为小写字母以供显示。这是 UPPER 函数的逆函数。 LOWER 对非字母字符没有影响。它保留不变的标点符号、数字以及前导和尾随空格。

LOWER 不强制将数字解释为字符串。 SQL 将数字转换为规范形式,删除前导零和尾随零。指定为字符串的数字不会转换为规范形式,并保留前导零和尾随零。

LCASE 函数也可用于将大写字母转换为小写字母。

LOWER 对排序没有影响。 %SQLUPPER 函数是 SQL 中为不区分大小写的排序规则转换数据值的首选方法。

示例

以下示例以小写字母返回每个人的姓名:

SELECT Name,LOWER(Name) AS LowName
     FROM Sample.Person

LOWER 也适用于 Unicode(非 ASCII)字母字符,如以下嵌入式 SQL 示例所示,它将希腊字母从大写转换为小写:

/// d ##class(PHA.TEST.SQLFunction).Lower()
ClassMethod Lower()
{
	s a = $c(920, 913, 923, 913, 931, 931, 913)
	&sql(
		SELECT LOWER(:a)
			INTO :b
		FROM Sample.Person
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,a,!,b 
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).Lower()
 
ΘΑΛΑΣΣΑ
θαλασσα
0
0 101
文章 姚 鑫 · 三月 23, 2022 1m read

第九十章 SQL函数 LOG10

标量数值函数,它返回给定数值表达式的以 10 为底的对数。

大纲

{fn LOG10(expression)}

参数

  • expression - 数值表达式。

LOG10 返回 NUMERICDOUBLE 数据类型。如果表达式为 DOUBLE 数据类型,则 LOG10 返回 DOUBLE;否则,它返回 NUMERIC

描述

LOG10 返回表达式的以 10 为底的对数值。LOG10 返回一个精度为 21、小数位数为 18 的值。

LOG10 只能用作 ODBC 标量函数(使用大括号语法)。

示例

以下示例返回整数的以 10 为底的对数:

SELECT {fn LOG10(5)} AS Log10

0.698970004336018805

以下嵌入式 SQL 示例返回整数 110 的以 10 为底的对数值:

/// d ##class(PHA.TEST.SQLFunction).Log10()
ClassMethod Log10()
{
	s a = 1
	while a < 11 {
		&sql(
			SELECT {fn LOG10(:a)} INTO :b
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE
			q 
		} else {
			w !,"Log-10 of ",a," = ",b
			s a = a + 1 
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Log10()
 
Log-10 of 1 = 0
Log-10 of 2 = .301029995663981195
Log-10 of 3 = .477121254719662437
Log-10 of 4 = .60205999132796239
Log-10 of 5 = .698970004336018805
Log-10 of 6 = .778151250383643633
Log-10 of 7 = .845098040014256831
Log-10 of 8 = .903089986991943586
Log-10 of 9 = .954242509439324875
Log-10 of 10 = 1
0
0 71
文章 姚 鑫 · 三月 22, 2022 2m read

第八十九章 SQL函数 LOG

返回给定数值表达式的自然对数的标量数值函数。

大纲

{fn LOG(expression)}

参数

  • expression - 数值表达式。

LOG 返回 NUMERICDOUBLE 数据类型。如果表达式为 DOUBLE 数据类型,则 LOG 返回 DOUBLE;否则,它返回 NUMERIC

描述

LOG 返回表达式的自然对数(以 e 为底)。 LOG 返回一个精度为 21、小数位数为 18 的值。

LOG 只能用作 ODBC 标量函数(使用大括号语法)。

示例

以下示例返回整数的自然对数:

SELECT {fn LOG(5)} AS Logarithm

1.609437912434100375

以下嵌入式 SQL 示例显示了整数 110LOGEXP 函数之间的关系:

请注意,此处需要 ROUND 函数来纠正由系统计算限制引起的非常小的差异。在上面的示例中,ROUND 被任意设置为 12 位十进制数字。

/// d ##class(PHA.TEST.SQLFunction).Log()
ClassMethod Log()
{
	s a = 1
	while a < 11 {
		&sql(
			SELECT {fn LOG(:a)} INTO :b
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE 
			q 
		} else {
			w !,"Logarithm of ",a," = ",b 
		}
		&sql(
			SELECT ROUND({fn EXP(:b)},12) INTO :c
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE
			q 
		} else {
			w !,"Exponential of log ",b," = ",c
			s a = a + 1 
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Log()
 
Logarithm of 1 = 0
Exponential of log 0 = 1
Logarithm of 2 = .6931471805599453089
Exponential of log .6931471805599453089 = 2
Logarithm of 3 = 1.098612288668109691
Exponential of log 1.098612288668109691 = 3
Logarithm of 4 = 1.386294361119890618
Exponential of log 1.386294361119890618 = 4
Logarithm of 5 = 1.609437912434100375
Exponential of log 1.609437912434100375 = 5
Logarithm of 6 = 1.791759469228055002
Exponential of log 1.791759469228055002 = 6
Logarithm of 7 = 1.945910149055313306
Exponential of log 1.945910149055313306 = 7
Logarithm of 8 = 2.079441541679835929
Exponential of log 2.079441541679835929 = 8
Logarithm of 9 = 2.197224577336219384
Exponential of log 2.197224577336219384 = 9
Logarithm of 10 = 2.302585092994045684
Exponential of log 2.302585092994045684 = 10
0
0 113
文章 姚 鑫 · 三月 21, 2022 3m read

第八十八章 SQL函数 $LISTTOSTRING

从列表创建字符串的列表函数。

大纲

$LISTTOSTRING(list[,delimiter])

参数

  • list - 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。
  • delimiter - 可选 — 插入以分隔子字符串的分隔符。分隔符可以是一个或多个字符,指定为带引号的字符串。要连接不带分隔符的子字符串,请指定空字符串 ('')。如果不指定分隔符,则默认为逗号 (,) 字符。

描述

$LISTTOSTRING 采用 列表并将其转换为字符串。在结果字符串中,列表的元素由分隔符分隔。

列表以不使用分隔符的编码格式表示数据。因此,列表可以包含所有可能的字符,并且非常适合位串数据。 $LISTTOSTRING 将此列表转换为带有分隔元素的字符串。它留出一个指定的字符(或字符串)作为分隔符。可以使用 $PIECE 函数处理这些分隔元素。

注意:此处指定的分隔符不得出现在源数据中。 不区分用作分隔符的字符和用作数据字符的相同字符。

可以使用 $LISTTOSTRING 从串行容器字段中检索字段值作为分隔字符串。在以下示例中,Home 是一个串行容器字段。它包含列表元素 Home_StreetHome_CityHome_StateHome_Zip

SELECT Name,$LISTTOSTRING(Home,'^') AS HomeAddress
FROM Sample.Person

参数

list

包含一个或多个元素的编码字符串。可以使用 SQL $LISTBUILD 函数或 ObjectScript $LISTBUILD 函数创建列表。可以使用 SQL $LISTFROMSTRING 函数或 ObjectScript $LISTFROMSTRING 函数将分隔字符串转换为列表。可以使用 SQL $LIST 函数或 ObjectScript $LIST 函数从现有列表中提取列表。

如果列表参数中的表达式未计算为有效列表,则会发生 SQLCODE -400 错误。

delimiter

用于在输出字符串中分隔子字符串的字符(或字符串)。它可以是数字或字符串文字(用单引号括起来)、主变量或计算结果为字符串的表达式。

通常,定界符是在字符串数据中从不使用的指定字符,但仅用作分隔子字符串的定界符。定界符也可以是多字符串,其中的各个字符可以在字符串数据中使用。

如果不指定分隔符,则默认分隔符是逗号 (,) 字符。您可以指定一个空字符串 ('')作为分隔符;在这种情况下,子字符串连接起来没有分隔符。要将单引号字符指定为分隔符,请复制引号字符: '''' — 四个单引号字符。

示例

以下示例将列表字段的值转换为字符串,其中元素由冒号 (:) 字符分隔:

SELECT
Name,
FavoriteColors AS ColorList,
$LISTTOSTRING(FavoriteColors,':') AS ColorStrings
FROM Sample.Person
WHERE FavoriteColors IS NOT NULL
0
0 141
文章 姚 鑫 · 三月 20, 2022 4m read

第八十七章 SQL函数 $LISTSAME

比较两个列表并返回布尔值的列表函数。

大纲

$LISTSAME(list1,list2)

参数

  • list1 - 计算结果为有效列表的表达式。
  • list2 - 计算结果为有效列表的表达式。

描述

$LISTSAME 比较两个列表的内容,如果列表相同则返回 1。如果列表不相同,则 $LISTSAME 返回 0$LISTSAME 逐个元素地比较两个列表。对于两个相同的列表,它们必须包含相同数量的元素,并且 list1 中的每个元素必须与 list2 中的相应元素匹配。

$LISTSAME 使用它们的字符串表示来比较列表元素。 $LISTSAME 比较区分大小写。 $LISTSAME 按从左到右的顺序逐个元素地比较两个列表。因此,$LISTSAME 在遇到第一个不匹配的列表元素对时返回值 0;它不检查后续项目以确定它们是否是有效的列表元素。

此函数返回 SMALLINT 类型的数据。

参数

list (list1 and list2)

列表是包含一个或多个元素的编码字符串。可以使用 SQL $LISTBUILD 函数或 ObjectScript $LISTBUILD 函数创建列表。可以使用 SQL $LISTFROMSTRING 函数或 ObjectScript $LISTFROMSTRING 函数将分隔字符串转换为列表。可以使用 SQL $LIST 函数或 ObjectScript $LIST 函数从现有列表中提取列表。

以下是有效列表的示例:

  • $LISTBUILD('a','b','c'):一个三元素列表。
  • $LISTBUILD('a','','c'):三元素列表,第二个元素为空字符串值。
  • $LISTBUILD('a',,'c')$LISTBUILD('a',NULL,'c'):三元素列表,第二个元素没有值。
  • $LISTBUILD(NULL,NULL)$LISTBUILD(,NULL):包含两个元素的列表,其中的元素没有值。
  • $LISTBUILD(NULL)$LISTBUILD():单元素列表,该元素没有值。

如果列表参数为 NULL,则 $LISTSAME 返回 NULL。如果列表参数不是有效列表(并且不是 NULL) SQL 会生成 SQLCODE -400 致命错误。

示例

以下嵌入式 SQL 示例使用 $LISTSAME 比较两个列表参数:

/// d ##class(PHA.TEST.SQLFunction).ListSame()
ClassMethod ListSame()
{
	s a = $lb("Red", , "Yellow", "Green", "", "Violet")
	s b = $lb("Red", , "Yellow", "Green", "", "Violet")
	&sql(
		SELECT $LISTSAME(:a,:b)
			INTO :c 
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} elseif c=1 { 
		w "lists a and b are the same",! 
	} else { 
		w "lists a and b are not the same",! 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListSame()
lists a and b are the same

以下 SQL 示例比较具有 NULL、缺失或空字符串元素的列表:

  SELECT $LISTSAME($LISTBUILD('Red',NULL,'Blue'),$LISTBUILD('Red',,'Blue')) AS NullAbsent,
         $LISTSAME($LISTBUILD('Red',NULL,'Blue'),$LISTBUILD('Red','','Blue')) AS NullEmpty,
         $LISTSAME($LISTBUILD('Red',,'Blue'),$LISTBUILD('Red','','Blue')) AS AbsentEmpty
         
         
0	0	0

$LISTSAME 比较与 ObjectScript 等号使用的等价测试不同。等号将两个列表作为编码字符串(逐个字符)进行比较; $LISTSAME 逐个元素地比较两个列表。在比较数字和数字字符串时很容易看出这种区别,如下例所示:

/// d ##class(PHA.TEST.SQLFunction).ListSame1()
ClassMethod ListSame1()
{
	s a = $lb("365")
	s b = $lb(365)
	if a = b { 
		w "Equal sign: lists a and b are the same",! 
	} else { 
		w "Equal sign: lists a and b are not the same",! 
	}
	&sql(
		SELECT $LISTSAME(:a,:b)
			INTO :c 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} elseif c=1 { 
		w "$LISTSAME: lists a and b are the same",! 
	} else { 
		w "$LISTSAME: lists a and b are not the same",! 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListSame1()
Equal sign: lists a and b are not the same
$LISTSAME: lists a and b are the same
 

以下 SQL 示例比较了包含规范和非规范形式的数字和数字字符串的列表。比较数字列表元素和字符串列表元素时,字符串列表元素必须以规范形式表示数字;这是因为 IRIS 在执行比较之前总是将数字简化为规范形式。在以下示例中,$LISTSAME 比较字符串和数字。前三个 $LISTSAME 函数返回 1(相同);第四个 $LISTSAME 函数返回 0(不相同),因为字符串表示不是规范形式:

SELECT $LISTSAME($LISTBUILD('365'),$LISTBUILD(365)),
         $LISTSAME($LISTBUILD('365'),$LISTBUILD(365.0)),
         $LISTSAME($LISTBUILD('365.5'),$LISTBUILD(365.5)),
         $LISTSAME($LISTBUILD('365.0'),$LISTBUILD(365.0))
         
1	1	1	0
0
0 88
文章 姚 鑫 · 三月 19, 2022 4m read

第八十六章 SQL函数 $LISTLENGTH

返回指定列表中元素数量的列表函数。

大纲

$LISTLENGTH(list)

参数

  • list- 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。您可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。您可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。

描述

$LISTLENGTH 返回列表中元素的数量。

此函数返回 SMALLINT 类型的数据。

示例

以下嵌入式 SQL 示例返回 3,因为列表中有 3 个元素:

/// d ##class(PHA.TEST.SQLFunction).ListLength()
ClassMethod ListLength()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTLENGTH(:a) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).ListLength()
 
The number of elements is 3

以下 SQL 示例也返回 3,因为列表中有 3 个元素:

SELECT $LISTLENGTH($LISTBUILD('Red','Blue','Green'))

3

以下嵌入式 SQL 示例也返回 3。列表中有 3 个元素,但第二个元素不包含数据:

/// d ##class(PHA.TEST.SQLFunction).ListLength1()
ClassMethod ListLength1()
{
	s a = $lb("Red", , "Green")
	&sql(
		SELECT $LISTLENGTH(:a) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength1()
 
The number of elements is 3

在下面的 SQL 示例中,每个 $LISTLENGTH 返回 3,因为列表中有 3 个元素,尽管第二个元素不包含数据:

SELECT $LISTLENGTH($LISTBUILD('Red','','Green')),
       $LISTLENGTH($LISTBUILD('Red',NULL,'Green')),
       $LISTLENGTH($LISTBUILD('Red',,'Green'))
       
3	3	3

注意

无效列表

如果 list 不是有效的列表,则会生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).ListLength2()
ClassMethod ListLength2()
{
	s a = "fred"
	&sql(
		SELECT $LISTLENGTH(:a) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b ; Variable not set
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength2()
 
Error code;-400

如果使用 ObjectScript $LISTBUILD 函数构建一个仅包含空字符串的列表,则这是一个有效列表,包含一个元素:

/// d ##class(PHA.TEST.SQLFunction).ListLength3()
ClassMethod ListLength3()
{
	s a = $lb("")
	&sql(
		SELECT $LISTLENGTH(:a) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength3()
 
The number of elements is 1

null列表

SQL $LISTLENGTH 函数和ObjectScript $LISTLENGTH 函数在处理空列表(不包含元素的列表)的方式上有所不同。

以下三个嵌入式 SQL 示例显示 $LISTLENGTH SQL 函数如何处理空列表。在前两个示例中,list 是空字符串,并返回一个空字符串:

/// d ##class(PHA.TEST.SQLFunction).ListLength4()
ClassMethod ListLength4()
{
	s a = ""
	&sql(
		SELECT $LISTLENGTH(:a)
			INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength4()
 
The number of elements is
/// d ##class(PHA.TEST.SQLFunction).ListLength5()
ClassMethod ListLength5()
{
	&sql(
		SELECT $LISTLENGTH(NULL)
			INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).ListLength5()
 
The number of elements is

在第三个例子中,list 是值 $CHAR(0),它是一个无效的列表;生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).ListLength6()
ClassMethod ListLength6()
{
	&sql(
		SELECT $LISTLENGTH('')
			INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength6()
 
Error code;-400

请注意,这与 ObjectScript $LISTLENGTH 函数处理空列表的方式不同。在 ObjectScript 中,空字符串 ("") 用于表示空列表,即不包含任何元素的列表。因为它不包含列表元素,所以它的 $LISTLENGTH 计数为 0,如下例所示:

DHC-APP>   WRITE $LISTLENGTH("")
0

$LISTLENGTH 和嵌套列表

以下嵌入式 SQL 示例返回 3,因为 $LISTLENGTH 无法识别嵌套列表中的各个元素:

/// d ##class(PHA.TEST.SQLFunction).ListLength7()
ClassMethod ListLength7()
{
	s a = $lb("Apple", "Pear", $LISTBUILD("Walnut", "Pecan"))
	&sql(
		SELECT $LISTLENGTH(:a)
			INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The number of elements is ",b 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListLength7()
 
The number of elements is 3
0
0 101
文章 姚 鑫 · 三月 18, 2022 5m read

第八十五章 SQL函数 $LISTGET

返回列表中的元素或指定默认值的列表函数。

大纲

$LISTGET(list[,position[,default]])

参数

  • list - 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。
  • position - 可选 — 解释为指定列表中的位置的表达式。
  • default - 可选 — 如果列表元素具有未定义的值,则该表达式提供要返回的值。

描述

$LISTGET 将指定列表中的请求元素作为标准字符串返回。如果位置参数的值引用不存在的成员或标识具有未定义值的元素,则返回指定的默认值。

$LISTGET 函数与 $LIST 函数的单参数和双参数形式相同,只是在导致 $LIST 返回空字符串的条件下,$LISTGET 返回默认值。

此函数返回 VARCHAR 类型的数据。

可以使用 $LISTGET 从串行容器字段中检索字段值。在以下示例中,Home 是一个串行容器字段,其第三个元素是 Home_State

SELECT Name,$LISTGET(Home,3) AS HomeState
FROM Sample.Person

参数

list

包含一个或多个元素的编码字符串。可以使用 SQL $LISTBUILD 函数或 ObjectScript $LISTBUILD 函数创建列表。可以使用 SQL $LISTFROMSTRING 函数或 ObjectScript $LISTFROMSTRING 函数将分隔字符串转换为列表。可以使用 SQL $LIST 函数或 ObjectScript $LIST 函数从现有列表中提取列表。

position

位置参数必须计算为整数。如果省略,默认情况下,该函数检查列表的第一个元素。如果 position 参数的值为 -1,则相当于指定列表的最后一个元素。

default

字符串。如果省略默认参数,则默认值假定为零长度字符串。

示例

以下嵌入式 SQL 示例中的 $LISTGET 函数都返回“Red”,即列表中的第一个元素:

/// d ##class(PHA.TEST.SQLFunction).ListGet()
ClassMethod ListGet()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a),$LISTGET(:a,1)
			INTO :b,:c)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The one-arg element returned is ",b
		w !,"The two-arg element returned is ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet()
 
The one-arg element returned is Red
The two-arg element returned is Red

以下嵌入式 SQL 示例中的 $LISTGET 函数都返回“Green”,即列表中的第三个和最后一个元素:

/// d ##class(PHA.TEST.SQLFunction).ListGet1()
ClassMethod ListGet1()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a, 3),$LISTGET(:a, -1)
			INTO :b,:c)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The third element is ",b
		w !,"The last element is ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet1()
 
The third element is Green
The last element is Green

以下嵌入式 SQL 示例中的 $LISTGET 函数都在遇到列表中未定义的第二个元素时返回一个值。第一个返回问号 (?),用户将其定义为默认值。第二个返回空字符串,因为未指定默认值:

/// d ##class(PHA.TEST.SQLFunction).ListGet2()
ClassMethod ListGet2()
{
	s a = $lb("Red", , "Green")
	&sql(
		SELECT $LISTGET(:a, 2, '?'),$LISTGET(:a, 2)
			INTO :b,:c)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The default value is ",b
		w !,"The no-default value is ",c 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet2()
 
The default value is ?
The no-default value is

以下嵌入式 SQL 示例中的 $LISTGET 函数都指定了一个大于三元素列表中最后一个元素的位置。第一个返回空字符串,因为未指定默认值。第二个返回用户指定的默认值“ERR”

/// d ##class(PHA.TEST.SQLFunction).ListGet3()
ClassMethod ListGet3()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a, 4), $LISTGET(:a, 4, 'ERR')
			INTO :b,:c)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The no-default 4th element is ",b
		w !,"The default for 4th element is ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet3()
 
The no-default 4th element is
The default for 4th element is ERR

以下嵌入式 SQL 示例中的 $LISTGET 函数均返回空字符串:

/// d ##class(PHA.TEST.SQLFunction).ListGet4()
ClassMethod ListGet4()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a, 0), $LISTGET(NULL)
			INTO :b,:c
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The zero element is ",b
		w !,"The NULL element is ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet4()
 
The zero element is
The NULL element is

注意

无效的参数值

如果列表参数中的表达式未计算为有效列表,则会发生 SQLCODE -400 致命错误,因为 $LISTGET 返回变量仍未定义。即使提供了默认值也会发生这种情况,如以下嵌入式 SQL 示例所示:

/// d ##class(PHA.TEST.SQLFunction).ListGet5()
ClassMethod ListGet5()
{
	&sql(
		SELECT $LISTGET('fred', 1, 'failsafe') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"The non-list element is ",b  ; Variable not set
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet5()
 
Error code;-400

如果 position 参数的值小于 -1,则会发生 SQLCODE -400 致命错误,因为 $LISTGET 返回变量仍未定义。即使提供了默认值也会发生这种情况,如以下嵌入式 SQL 示例所示:

/// d ##class(PHA.TEST.SQLFunction).ListGet6()
ClassMethod ListGet6()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a ,-3, 'failsafe') INTO :c
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"A neg-num position returns ",c  ; Variable not set
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet6()
 
Error code;-400

position 是一个非数字值时,这不会发生:

/// d ##class(PHA.TEST.SQLFunction).ListGet7()
ClassMethod ListGet7()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTGET(:a,'g','failsafe') INTO :c
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		w !,"A nonnumeric position returns ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListGet7()
 
A nonnumeric position returns failsafe
0
0 85
文章 姚 鑫 · 三月 17, 2022 2m read

第八十四章 SQL函数 $LISTFROMSTRING

从字符串创建列表的列表函数。

大纲

$LISTFROMSTRING(string[,delimiter])

参数

  • string - 要转换为 列表的字符串。此字符串包含一个或多个元素,由分隔符分隔。分隔符不会成为生成的列表的一部分。
  • delimiter - 可选 — 用于分隔字符串中的子字符串(元素)的分隔符。将分隔符指定为带引号的字符串。如果未指定分隔符,则默认为逗号 (,) 字符。

描述

$LISTFROMSTRING 接受一个包含分隔元素的带引号的字符串并返回一个列表。列表以不使用分隔符的编码格式表示数据。因此,列表可以包含所有可能的字符,并且非常适合位串数据。使用 ObjectScript 和 SQL $LIST 函数处理列表。

参数

string

字符串文字(用单引号括起来)、数字或计算结果为字符串的变量或表达式。此字符串可以包含一个或多个子字符串(元素),由分隔符分隔。字符串数据元素不得包含分隔符(或字符串),因为分隔符不包含在输出列表中。

delimiter

用于在输入字符串中分隔子字符串的字符(或字符串)。它可以是数字或字符串文字(括在单引号中)、变量的名称或计算结果为字符串的表达式。

通常,定界符是在字符串数据中从不使用的指定字符,但仅用作分隔子字符串的定界符。定界符也可以是多字符串,其中的各个字符可以在字符串数据中使用。如果不指定分隔符,则默认分隔符是逗号 (,) 字符。

示例

以下嵌入式 SQL 示例采用由空格分隔的名称字符串,并创建一个列表:

/// d ##class(PHA.TEST.SQLFunction).ListFromString()
ClassMethod ListFromString()
{
	s names = "Deborah Noah Martha Bowie"
	&sql(
		SELECT $LISTFROMSTRING(:names,' ')
			INTO :namelist
	)
	if SQLCODE '= 0 {
		w !,"Error code;",SQLCODE 
	} else {
		for n = 1 : 1 : $ll(namelist) {
			w !,"element ",n,": ",$li(namelist ,n)
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFromString()
 
element 1: Deborah
element 2: Noah
element 3: Martha
element 4: Bowie

以下嵌入式 SQL 示例使用默认分隔符(逗号字符),并创建一个列表:

/// d ##class(PHA.TEST.SQLFunction).ListFromString1()
ClassMethod ListFromString1()
{
	s names = "Deborah, Noah ,Martha, Bowie"
	&sql(
		SELECT $LISTFROMSTRING(:names)
			INTO :namelist
	)
	if SQLCODE = 0 {
		for n = 1 : 1 : $ll(namelist) {
			w !,"element ",n,": ",$li(namelist ,n)
		}
	} else {
		w !,"Error code;",SQLCODE  
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).ListFromString1()
 
element 1: Deborah
element 2:  Noah
element 3: Martha
element 4:  Bowie
0
0 126
文章 姚 鑫 · 三月 16, 2022 4m read

第八十三章 SQL函数 $LISTFIND

列表函数,用于在指定列表中搜索请求的值。

大纲

$LISTFIND(list,value[,startafter])

参数

  • list - 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。您可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。
  • value - 包含搜索元素的表达式。一个字符串。
  • startafter - 可选 — 解释为列表位置的整数表达式。搜索从该位置之后的元素开始。0–1 是有效值; –1 从不返回元素。零是默认值。

描述

$LISTFIND 在指定列表中搜索请求值的第一个实例。搜索从 startafter 参数指示的位置之后的元素开始。如果省略 startafter 参数,则 $LISTFIND 假定 startafter 值为 0 并从第一个元素(元素 1)开始搜索。如果找到该值,则 $LISTFIND 返回匹配元素的位置。如果未找到该值,则 $LISTFIND 返回 0。如果 startafter 参数的值引用不存在的列表成员,则 $LISTFIND 函数也将返回 0

此函数返回 SMALLINT 类型的数据。

示例

以下嵌入式 SQL 示例返回 2,即请求字符串第一次出现的位置:

/// d ##class(PHA.TEST.SQLFunction).ListFind()
ClassMethod ListFind()
{
	s a = $lb("Red","Blue","Green")
	&sql(
		SELECT $LISTFIND(:a, 'Blue') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind()
 
The position is 2

以下嵌入式 SQL 示例返回 0,表示未找到请求的字符串:

/// d ##class(PHA.TEST.SQLFunction).ListFind1()
ClassMethod ListFind1()
{
	s a = $lb("Red","Blue","Green")
	&sql(
		SELECT $LISTFIND(:a, 'Orange') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind1()
 
The position is 0

以下三个嵌入式 SQL 示例显示了使用 startafter 参数的效果。第一个示例没有找到请求的字符串并返回 0,因为请求的字符串出现在 startafter 位置:

/// d ##class(PHA.TEST.SQLFunction).ListFind2()
ClassMethod ListFind2()
{
	s a = $lb("Red","Blue","Green")
	&sql(
		SELECT $LISTFIND(:a, 'Blue', 2) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind2()
 
The position is 0

第二个示例通过将 startafter 设置为零(默认值)来在第一个位置找到请求的字符串:

/// d ##class(PHA.TEST.SQLFunction).ListFind3()
ClassMethod ListFind3()
{
	s a = $lb("Red","Blue","Green")
	&sql(
		SELECT $LISTFIND(:a, 'Red', 0) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind3()
 
The position is 1

第三个示例找到请求的字符串的第二次出现并返回 5,因为第一次出现在 startafter 位置之前:

/// d ##class(PHA.TEST.SQLFunction).ListFind4()
ClassMethod ListFind4()
{
	s a = $lb("Red","Blue","Green","Yellow","Blue")
	&sql(
		SELECT $LISTFIND(:a, 'Blue', 3) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind4()
 
The position is 5

$LISTFIND 函数只匹配完整的元素。因此,以下示例返回 0,因为列表中没有元素等于字符串“B”,尽管所有元素都包含“B”

/// d ##class(PHA.TEST.SQLFunction).ListFind5()
ClassMethod ListFind5()
{
	s a = $lb("ABC", "BCD", "BBB")
	&sql(
		SELECT $LISTFIND(:a,'B') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind5()
 
The position is 0

注意

无效的参数值

如果列表参数中的表达式未计算为有效列表,则 $LISTFIND 函数会生成 SQLCODE -400 致命错误。

/// d ##class(PHA.TEST.SQLFunction).ListFind6()
ClassMethod ListFind6()
{
	s a = "Blue"
	&sql(
		SELECT $LISTFIND(:a, 'Blue') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind6()
 
Error code -400

如果 startafter 参数的值为 -1,则 $LISTFIND 始终返回零 (0)

/// d ##class(PHA.TEST.SQLFunction).ListFind7()
ClassMethod ListFind7()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTFIND(:a, 'Blue', -1) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind7()
 
The position is 0

如果 startafter 参数的值小于 -1,则调用 $LISTFIND 函数会生成 SQLCODE -400 致命错误。

/// d ##class(PHA.TEST.SQLFunction).ListFind8()
ClassMethod ListFind8()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTFIND(:a, 'Blue', -3) INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The position is ",b 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListFind8()
 
Error code -400
0
0 132
文章 姚 鑫 · 三月 15, 2022 4m read

第八十二章 SQL函数 $LISTDATA

列表函数,指示指定元素是否存在并具有数据值。

大纲

$LISTDATA(list[,position])

参数

  • list - 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。您可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。您可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。
  • position - 可选 — 指定列表中元素的整数表达式。

描述

$LISTDATA 检查列表中请求元素中的数据。如果位置参数指示的元素在列表中并且具有数据值,则 $LISTDATA 返回值 1。如果元素不在列表中或没有数据值,则 $LISTDATA 返回值 0。

此函数返回 SMALLINT 类型的数据。

参数

list

包含一个或多个元素的编码字符串。可以使用 SQL $LISTBUILD 函数或 ObjectScript $LISTBUILD 函数创建列表。可以使用 SQL $LISTFROMSTRING 函数或 ObjectScript $LISTFROMSTRING 函数将分隔字符串转换为列表。可以使用 SQL $LIST 函数或 ObjectScript $LIST 函数从现有列表中提取列表。

position

如果省略 position 参数,$LISTDATA 将计算第一个元素。如果 position 参数的值为 -1,则相当于指定列表的最后一个元素。如果 position 参数的值引用了一个不存在的列表成员,则 $LISTDATA 返回 0

示例

以下嵌入式 SQL 示例显示了 position 参数的各种值的结果。

以下所有 $LISTDATA 语句都返回值 1

/// d ##class(PHA.TEST.SQLFunction).ListData()
ClassMethod ListData()
{
	k Y
	s a = $lb("Red", , Y, "", "Green")
	&sql(
		SELECT $LISTDATA(:a), $LISTDATA(:a,1), 
		$LISTDATA(:a,4), $LISTDATA(:a,5), $LISTDATA(:a,-1)
		INTO :b,:c, :d, :e, :f
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"1st element status  ",b  ; 1st element default
		w !,"1st element status  ",c  ; 1st element specified
		w !,"4th element status  ",d  ; 4th element null string
		w !,"5th element status  ",e  ; 5th element in 5-element list
		w !,"last element status ",f  ; last element in 5-element list
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListData()
 
1st element status  1
1st element status  1
4th element status  1
5th element status  1
last element status 1

以下 $LISTDATA 语句为相同的五元素列表返回值 0

/// d ##class(PHA.TEST.SQLFunction).ListData1()
ClassMethod ListData1()
{
	k Y
	s a = $LISTBUILD("Red", , Y, "", "Green")
	&sql(
		SELECT $LISTDATA(:a,2), $LISTDATA(:a,3), 
			$LISTDATA(:a,0), $LISTDATA(:a,6)
		INTO :b,:c, :d, :e
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"2nd element status ",b  ; 2nd element is undefined
		w !,"3rd element status ",c  ; 3rd element is killed variable
		w !,"0th element status ",d  ; zero position nonexistent
		w !,"6th element status ",e  ; 6th element in 5-element list
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListData1()
 
2nd element status 0
3rd element status 0
0th element status 0
6th element status 0

注意

无效的参数值

如果列表参数中的表达式未计算为有效列表,则会发生 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).ListData2()
ClassMethod ListData2()
{
	&sql(
		SELECT $LISTDATA('fred') INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The the element is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListData2()
 
Error code -400

如果 position 参数的值小于 -1,则会发生 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).ListData3()
ClassMethod ListData3()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTDATA(:a, -3) INTO :c
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"A neg-num position status ",c 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).ListData3()
 
Error code -400

position 是一个非数字值时,不会报错:

/// d ##class(PHA.TEST.SQLFunction).ListData4()
ClassMethod ListData4()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTDATA(:a, 'g') INTO :c
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"A nonnumeric position status ",c 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).ListData4()
 
A nonnumeric position status 0
0
0 86
文章 姚 鑫 · 三月 14, 2022 5m read

第八十一章 SQL函数 $LISTBUILD

从字符串构建列表的列表函数。

大纲

$LISTBUILD(element [,...])

参数

  • element - 任何表达式,或逗号分隔的表达式列表

描述

$LISTBUILD 接受一个或多个表达式,并为每个表达式返回一个包含一个元素的列表。

以下函数可用于创建列表:

  • $LISTBUILD,它从多个字符串创建一个列表,每个元素一个字符串。
  • $LISTFROMSTRING,它从包含多个分隔元素的单个字符串创建一个列表。
  • $LIST,从现有列表中提取子列表。

$LISTBUILD 与其他 SQL 列表函数一起使用:$LIST$LISTDATA$LISTFIND$LISTFROMSTRING$LISTGET$LISTLENGTH$LISTTOSTRING

注意:$LISTBUILD 和其他 $LIST 函数使用优化的二进制表示来存储数据元素。出于这个原因,等效性测试可能无法对某些 $LIST 数据按预期工作。在其他情况下可能被视为等效的数据可能具有不同的内部表示。例如,$LISTBUILD(1) 不等于 $LISTBUILD('1')

出于同样的原因,$LISTBUILD 返回的列表字符串值不应用于使用分隔符的字符搜索和解析函数,例如 $PIECE$LENGTH 的两个参数形式。由 $LISTBUILD 创建的列表中的元素不使用字符分隔符进行标记,因此可以包含任何字符。

示例

以下嵌入式 SQL 示例采用三个字符串并生成一个三元素列表:

/// d ##class(PHA.TEST.SQLFunction).Lb()
ClassMethod Lb()
{
	s x = "Red"
	s y = "White"
	s z = "Blue"
	&sql(
		SELECT $LISTBUILD(:x, :y, :z)
		INTO :listout
	)
	if SQLCODE = 0 {
		w listout," length ",$LISTLENGTH(listout)
	} else {
		w "Error code:",SQLCODE
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).Lb()
RedWhiteBlue length 3

注意

省略参数

省略元素表达式会产生一个值为 NULL 的元素。例如,以下嵌入式 SQL 包含两个 $LISTBUILD 语句,它们都生成一个三元素列表,其第二个元素具有未定义 (NULL) 值:

/// d ##class(PHA.TEST.SQLFunction).Lb1()
ClassMethod Lb1()
{
	s x = "Red"
	s y = "White"
	s z = "Blue"
	&sql(
		SELECT $LISTBUILD(:x, ,:z),
			$LISTBUILD(:x, '', :z)
		INTO :list1, :list2)
	if SQLCODE = 0 {
		w list1," length ",$LISTLENGTH(list1),!
		w list2," length ",$LISTLENGTH(list2)
	} else {
		w "Error code:",SQLCODE
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Lb1()
RedBlue length 3
RedBlue length 3

此外,如果 $LISTBUILD 表达式未定义,则相应的列表元素具有未定义的值。以下嵌入式 SQL 示例生成一个双元素列表,其第一个元素为“Red”,第二个元素具有未定义的值:

/// d ##class(PHA.TEST.SQLFunction).Lb2()
ClassMethod Lb2()
{
	&sql(
		SELECT $LISTBUILD('Red',:z)
		INTO :list1
	)
	if SQLCODE = 0 {
		w list1," length ",$LISTLENGTH(list1)
	} else {
		w "Error code:",SQLCODE
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Lb2()
Red length 2

以下嵌入式 SQL 示例生成一个包含两个元素的列表。尾随逗号表示第二个元素具有未定义的值:

/// d ##class(PHA.TEST.SQLFunction).Lb3()
ClassMethod Lb3()
{
	&sql(
		SELECT $LISTBUILD('Red',)
		INTO :list1
	)
	if SQLCODE = 0 {
		w list1," length ",$LISTLENGTH(list1)
	} else {
		w "Error code:",SQLCODE
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Lb3()
Red length 2

不提供任何参数

调用不带参数的 $LISTBUILD 函数会返回一个列表,其中包含一个数据值未定义的元素。这与 NULL 不同。以下是创建“空”列表的有效 $LISTBUILD 语句:

/// d ##class(PHA.TEST.SQLFunction).Lb4()
ClassMethod Lb4()
{
	&sql(
		SELECT $LISTBUILD(),
			$LISTBUILD(NULL)
		INTO :list1, :list2
	)
	if SQLCODE = 0 {
		ZZDUMP list1
		w !,"length ",$LISTLENGTH(list1),!
		ZZDUMP list2
		w !,"length ",$LISTLENGTH(list2),!
	} else {
		w "Error code:",SQLCODE
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Lb4()
 
0000: 01                                                      .
length 1
 
0000: 02 01                                                   ..
length 1

以下是创建包含空字符串的列表元素的有效 $LISTBUILD 语句:

/// d ##class(PHA.TEST.SQLFunction).Lb5()
ClassMethod Lb5()
{
	&sql(
		SELECT $LISTBUILD(''),
	          $LISTBUILD(CHAR(0))
		INTO :list1, :list2
	)
	if SQLCODE = 0 {
		ZZDUMP list1
		w !,"length ",$LISTLENGTH(list1),!
		ZZDUMP list2
		w !,"length ",$LISTLENGTH(list2),!
	} else {
		w "Error code:",SQLCODE
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).Lb5()
 
0000: 03 01 00                                                ...
length 1
 
0000: 03 01 00                                                ...
length 1

嵌套List

列表的元素本身可能是一个列表。例如,以下语句生成一个三元素列表,其第三个元素是二元素列表“Walnut,Pecan”


SELECT $LISTBUILD('Apple','Pear',$LISTBUILD('Walnut','Pecan'))

0x07014170706C650601506561721101080157616C6E75740701506563616E

连接List

使用 SQL 连接运算符 (||) 连接两个列表的结果是另一个列表。例如,以下 SELECT 项生成相同的列表“A,B,C”

SELECT $LISTBUILD('A','B','C') AS List,
  $LISTBUILD('A','B')||$LISTBUILD('C') AS CatList
0x030141030142030143	ABC

在以下示例中,前两个选择项生成相同的二元素列表;第三个选择项导致 NULL(因为将 NULL 连接到任何内容都会导致 NULL);第四个和第五个选择项产生相同的三元素列表:

SELECT
  $LISTBUILD('A','B') AS List,
  $LISTBUILD('A','B')||'' AS CatEStr,
  $LISTBUILD('A','B')||NULL AS CatNull,
  $LISTBUILD('A','B')||$LISTBUILD('') AS CatEList,
  $LISTBUILD('A','B')||$LISTBUILD(NULL) AS CatNList

image

Unicode

如果列表元素中的一个或多个字符是宽 (Unicode) 字符,则该元素中的所有字符都表示为宽字符。为了确保跨系统的兼容性,$LISTBUILD 总是以相同的顺序存储这些字节,而不管硬件平台如何。宽字符表示为字节字符串。

0
0 78
文章 姚 鑫 · 三月 13, 2022 5m read

第八十章 SQL函数 $LIST(二)

示例

在以下嵌入式 SQL 示例中,两个 WRITE 语句都返回“Red”,即列表中的第一个元素。第一个默认写入第一个元素,第二个写入第一个元素,因为位置参数设置为 1

/// d ##class(PHA.TEST.SQLFunction).Li4()
ClassMethod Li4()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(SELECT $LIST(:a), $LIST(:a,1)
		INTO :b,:c )
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The one-arg sublist is ",b
		w !,"The two-arg sublist is ",c }
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li4()
 
The one-arg sublist is Red
The two-arg sublist is Red

以下嵌入式 SQL 示例返回列表中的第二个元素“Blue”

/// d ##class(PHA.TEST.SQLFunction).Li5()
ClassMethod Li5()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a,2)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The second element is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li5()
 
The second element is Blue

以下嵌入式 SQL 示例返回“Red Blue”,这是一个双元素列表字符串,从列表中的第一个元素开始,到第二个元素结束。使用 ZZDUMP 而不是 WRITE,因为列表字符串包含特殊(非打印)编码字符:

/// d ##class(PHA.TEST.SQLFunction).Li6()
ClassMethod Li6()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a,1,2)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The encoded sublist is"
		ZZDUMP b   ; Prints "Red Blue " 
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).Li6()
 
The encoded sublist is
0000: 05 01 52 65 64 06 01 42 6C 75 65                        ..Red..Blue

以下嵌入式 SQL 示例返回未知长度列表中的最后一个元素。在这里,最后一个元素首先作为普通字符串返回,然后作为编码列表字符串返回:

/// d ##class(PHA.TEST.SQLFunction).Li7()
ClassMethod Li7()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LISTLENGTH(:a), $LIST(:a, -1)
		INTO :b,:plain 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		&sql(
			SELECT $LIST(:a,:b,-1)
			INTO :encoded
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE 
		} else {
			w !,"The final element as a string: ",plain
			w !,"The final element as an encoded string: "
			ZZDUMP encoded 
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li7()
 
The final element as a string: Green
The final element as an encoded string:
0000: 07 01 47 72 65 65 6E                                    ..Green

注意

无效的参数值

如果列表参数中的表达式未计算为有效列表,则会生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).Li8()
ClassMethod Li8()
{
	s a = "the quick brown fox"
	&sql(
		SELECT $LIST(:a, 1)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The sublist is"
		ZZDUMP b   ; Variable not set 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li8()
 
Error code -400

如果 position 参数或 end 参数的值小于 -1,则会生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).Li9()
ClassMethod Li9()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a, -2, 3)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The sublist is"
		ZZDUMP b   ; Variable not set 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li9()
 
Error code -400

如果 position 参数的值引用了一个不存在的列表成员并且没有使用 end 参数,则会生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).Li10()
ClassMethod Li10()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a, 7)
		INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The sublist is"
		ZZDUMP b   ; Variable not set
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li10()
 
Error code -400

但是,如果使用 end 参数,则不会发生错误,并且返回 null 字符串。

/// d ##class(PHA.TEST.SQLFunction).Li11()
ClassMethod Li11()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a, 7, -1)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"Error code ",SQLCODE
		w !,"The sublist is"
		ZZDUMP b   ; Prints a null string 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li11()
 
Error code 0
The sublist is

如果 position 参数的值标识具有未定义值的元素,则会生成 SQLCODE –400 致命错误:

/// d ##class(PHA.TEST.SQLFunction).Li12()
ClassMethod Li12()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a, 2)
		INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The sublist is"
		ZZDUMP b   ; Variable not set
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li12()
 
The sublist is
0000: 42 6C 75 65                                             Blue

两个参数和三个参数 $LIST

$LIST(list,1) 不等价于 $LIST(list,1,1) 因为前者返回一个字符串,而后者返回一个单元素列表字符串。如果没有要返回的元素,则双参数形式不返回值;三参数形式返回一个空字符串。

Unicode

如果一个 Unicode 字符出现在列表元素中,则整个列表元素将表示为 Unicode(宽)字符。列表中的其他元素不受影响。

以下嵌入式 SQL 示例显示了两个列表。 a 列表由两个仅包含 ASCII 字符的元素组成。 b 列表由两个元素组成:第一个元素包含一个 Unicode 字符($CHAR(960) = pi 符号);第二个元素仅包含 ASCII 字符。

/// d ##class(PHA.TEST.SQLFunction).Li13()
ClassMethod Li13()
{
	s a = $lb("ABC" _ $CHAR(68), "XYZ")
	s b = $lb("ABC" _ $CHAR(960), "XYZ")
	&sql(
		SELECT $LIST(:a, 1), $LIST(:a, 2), $LIST(:b, 1), $LIST(:b, 2)
		INTO :a1, :a2, :b1, :b2 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The ASCII list a elements: "
		ZZDUMP a1
		ZZDUMP a2
		w !,"The Unicode list b elements: "
		ZZDUMP b1
		ZZDUMP b2 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Li13()
 
The ASCII list a elements:
0000: 41 42 43 44                                             ABCD
0000: 58 59 5A                                                XYZ
The Unicode list b elements:
0000: 0041 0042 0043 03C0                                     ABCπ
0000: 58 59 5A                                                XYZ

请注意, IRIS 将 b 的第一个元素完全编码为宽 Unicode 字符。 b 的第二个元素不包含 Unicode 字符,因此 IRIS 使用窄 ASCII 字符对其进行编码。

0
0 134
文章 姚 鑫 · 三月 12, 2022 4m read

第七十九章 SQL函数 $LIST(一)

返回列表中元素的列表函数。

大纲

$LIST(list[,position[,end]])

参数

  • list - 计算结果为有效列表的表达式。列表是包含一个或多个元素的编码字符串。可以使用 SQL 或 ObjectScript 的 $LISTBUILD$LISTFROMSTRING 函数创建列表。可以使用 SQL 或 ObjectScript $LIST 函数从现有列表中提取列表。
  • position - 可选 - 指定列表中的起始位置。计算结果为整数的表达式。
  • end - 可选 - 指定列表中的结束位置。计算结果为整数的表达式。

描述

$LIST 从列表中返回元素。返回的元素取决于使用的参数。

  • $LIST(list) 将列表中的第一个元素作为文本字符串返回。
  • $LIST(list,position) 将指定位置指示的元素作为文本字符串返回。位置参数必须计算为整数。
  • $LIST(list,position,end) 返回一个“子列表”(编码的列表字符串),其中包含从指定开始位置到指定结束位置的列表元素。

此函数返回 VARCHAR 类型的数据。

参数

list

包含一个或多个元素的编码字符串。可以使用 SQL $LISTBUILD 函数或 ObjectScript $LISTBUILD 函数创建列表。可以使用 SQL $LISTFROMSTRING 函数或 ObjectScript $LISTFROMSTRING 函数将分隔字符串转换为列表。您可以使用 SQL $LIST 函数或 ObjectScript $LIST 函数从现有列表中提取列表。

position

要返回的列表元素的位置。列表元素从 1 开始计数。如果省略 position,则返回第一个元素。如果 position 的值是 0 或大于列表中的元素数, SQL 不会返回值。如果 position 的值为负一 (–1),则 $LIST 返回列表中的最后一个元素。

/// d ##class(PHA.TEST.SQLCommand).Li()
ClassMethod Li()
{
   s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a,-1)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The last element is ",b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Li()
 
The last element is Green

如果指定了 end 参数,则 position 指定元素范围中的第一个元素。即使只返回一个元素(当位置和结束是相同的数字时),该元素也会作为编码列表字符串返回。因此,$LIST(x,2)(将元素作为普通字符串返回)与 $LIST(x,2,2)(将元素作为编码列表字符串返回)不同。

end

元素范围内最后一个元素的位置。必须指定位置才能指定结束。当指定 end 时,返回的值是一个编码的列表字符串。由于这种编码,此类字符串只能由其他 $LIST 函数处理。

如果 end 的值为:

  • 大于位置,则返回包含元素列表的编码字符串。
  • 等于位置,返回一个包含一个元素的编码字符串。
  • 小于位置,不返回值。
  • 大于列表中的元素个数,相当于指定列表中的最后一个元素。
  • 负一 (–1),相当于指定列表中的最后一个元素。

指定 end 时,可以指定零 (0) 的位置值。在这种情况下,0 等于 1

使用列表

一个表可以包含一个或多个列表字段。因为列表是编码字符串,所以这些字段可以定义为数据类型 %List (%Library.List) 或数据类型 VARCHAR。数据类型 %List 的字段可以标识为 CType(客户端数据类型)= 6

数据类型在插入或更新时不限制字段的允许值。因此,用户必须确保 List 字段中的所有数据值都是 List 编码字符串。如果 SQL $LIST 函数遇到未编码的字符串数据值,则 SELECT 操作将失败并返回带有 %msgSQLCODE -400,如下所示:Unexpected error occurred: <LIST>%0AmBuncommitted+1^%sqlcq.USER.cls61.1.

可以通过使用主变量或通过在 SQL 中指定 $LISTBUILD 将列表提供给 SQL $LIST 函数。两者都显示在以下嵌入式 SQL 示例中:

/// d ##class(PHA.TEST.SQLCommand).Li1()
ClassMethod Li1()
{
	s mylist = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:mylist, 2), $LIST($LISTBUILD('Red', 'Blue', 'Green'), 3)
		INTO :a,:b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The host varable list element is ",a,!
		w !,"The SQL $LISTBUILD list element is ",b,! 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Li1()
 
The host varable list element is Blue
 
The SQL $LISTBUILD list element is Green

可以使用 $LIST 函数从另一个列表中提取列表:

/// d ##class(PHA.TEST.SQLCommand).Li2()
ClassMethod Li2()
{
	s a = $lb("Red", "Blue", "Green")
	&sql(
		SELECT $LIST(:a,2, 3)
		INTO :b 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		&sql(
			SELECT $LIST(:b,1)
			INTO :c 
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE 
		} else {
			w !,"The element returned is ",c }
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Li2()
 
The element returned is Blue

在以下嵌入式 SQL 示例中,subList 不是有效的列表参数,因为它是作为普通字符串返回的单个元素,而不是编码列表字符串。只有 $LIST 的三参数形式返回编码列表字符串。在这种情况下,会生成 SQLCODE -400 致命错误:

/// d ##class(PHA.TEST.SQLCommand).Li3()
ClassMethod Li3()
{
	s a = $lb("Red","Blue","Green")
	&sql(
		SELECT $LIST(:a,2)
		INTO :sublist 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		&sql(
			SELECT $LIST(:sublist,1)
			INTO :c 
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE 
		} else {
			w !,"The sublist is"
			ZZDUMP c   ; Variable not set 
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Li3()
 
Error code -400
0
0 334
文章 姚 鑫 · 三月 11, 2022 5m read

第七十八章 SQL函数 $LENGTH

返回字符串中字符数或分隔子字符串数的字符串函数。

大纲

$LENGTH(expression[,delimiter])

参数

  • expression - 目标字符串。它可以是数值、字符串文字、任何变量的名称或任何有效的表达式。
  • delimiter - 可选 — 在目标字符串中划分不同子字符串的字符串。它必须是字符串文字,但可以是任意长度。括起来的引号是必需的。

$LENGTH 返回 SMALLINT 数据类型。

描述

$LENGTH 返回指定字符串中的字符数或指定字符串中的子字符串数,具体取决于使用的参数。

  • $LENGTH(expression) 返回字符串中的字符数。如果表达式为空字符串 (''),则 $LENGTH 返回 0。如果表达式为 NULL,则 $LENGTH 返回 0
  • $LENGTH(expression,delimiter) 返回字符串中子字符串的数量。 $LENGTH 返回由指定分隔符相互分隔的子字符串的数量。此数字始终等于在表达式字符串中找到的分隔符实例的数量加一。

$LENGTH(expression) 和其他长度函数

$LENGTH(expression) 和其他长度函数(LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH)都执行以下操作:

  • $LENGTH 返回字段的逻辑(内部数据存储)值的长度,而不是显示值,无论 SelectMode 设置如何。所有 SQL 函数始终使用字段的内部存储值。
  • $LENGTH 返回数字的规范形式的长度。规范形式的数字不包括前导零和尾随零、前导符号(单个减号除外)和尾随小数分隔符。 $LENGTH 返回数字字符串的字符串长度。数字字符串不会转换为规范形式。
  • $LENGTH 不排除字符串中的前导空格。可以使用 LTRIM 函数从字符串中删除前导空格。

在执行以下操作时,$LENGTH 与其他长度函数(LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH)不同:

  • $LENGTH 不排除尾随空格和终止符。CHARACTER_LENGTHCHAR_LENGTHDATALENGTH 也不排除尾随空格和终止符。 LENGTH 不包括尾随空格和字符串终止字符。
  • 如果传递一个 NULL 值,则 $LENGTH 返回 0,如果传递一个空字符串,则返回 0。如果传递 NULL 值,则 LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH 返回 NULL,如果传递空字符串,则返回 0
  • $LENGTH 不支持数据流字段。为字符串表达式指定流字段会导致 SQLCODE -37LENGTH 也不支持流字段。 CHARACTER_LENGTHCHAR_LENGTHDATALENGTH 函数确实支持数据流字段。
  • $LENGTH 返回数据类型 SMALLINT。所有其他长度函数都返回数据类型 INTEGER

NULL 和空字符串参数

$LENGTH(expression) 不区分空字符串 ('') 和 NULL(缺少值)。它为空字符串 ('') 值和 NULL 返回长度 0

如果没有匹配,带有非空分隔符的 $LENGTH(expression,delimiter) 将返回 1 的分隔子字符串计数。完整字符串是不包含分隔符的单个子字符串。即使表达式为空字符串 ('') 或表达式为 NULL,也是如此。但是,空字符串会匹配自身,返回值 2

下表显示了字符串(‘abc’)、空字符串(‘’)或NULL表达式值与不匹配的字符串(‘^’)、空字符串(‘’)或NULL分隔符值的可能组合:

   
$LENGTH(NULL) = 0$LENGTH('') = 0$LENGTH('abc') = 3
$LENGTH(NULL,NULL) = 0$LENGTH('',NULL) = 0$LENGTH(’abc‘,NULL) = 0
$LENGTH(NULL,'') = 1$LENGTH('','') = 2$LENGTH(’abc‘,'') = 1
$LENGTH(NULL,'^') = 1$LENGTH(’‘,'^') = 1$LENGTH('abc','^') = 1

示例

以下示例返回 6,即字符串的长度:

SELECT $LENGTH('ABCDEG') AS StringLength

6

以下示例返回 3,即字符串中的子字符串数,由美元符号 ($) 字符分隔。

SELECT $LENGTH('ABC$DEF$EFG','$') AS SubStrings

3

如果在字符串 $LENGTH 中找不到指定的分隔符,则返回 1,因为唯一的子字符串是字符串本身:

SELECT $LENGTH('ABCDEG','$') AS SubStrings

1

在下面的嵌入式 SQL 示例中,第一个 $LENGTH 函数返回 11,即 a 中的字符数(当然包括空格字符)。第二个 $LENGTH 函数返回 2,即 a 中使用 b(空格字符)作为子字符串分隔符的子字符串数。

/// d ##class(PHA.TEST.SQLCommand).Length1()
ClassMethod Length1()
{
	s a = "HELLO WORLD"
	s b = " "
	&sql(
		SELECT 
			$LENGTH(:a),
			$LENGTH(:a,:b)
		INTO :a1,:a2 
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The input string: ",a
		w !,"Number of characters: ",a1
		w !,"Number of substrings: ",a2 }
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Length1()
 
The input string: HELLO WORLD
Number of characters: 11
Number of substrings: 2

以下示例返回 0,因为测试的字符串是空字符串:

SELECT $LENGTH(NULL) AS StringLength

0

以下示例返回 1,因为指定了分隔符但未找到。有一个子字符串,即空字符串:

SELECT $LENGTH(NULL,'$') AS SubStrings

1

以下示例返回 0,因为分隔符是空字符串:

SELECT $LENGTH('ABCDEFG',NULL) AS SubStrings

0

注意

$LENGTH、$PIECE 和 $LIST

  • 带有一个参数的 $LENGTH 返回字符串中的字符数。此函数可与 $EXTRACT 函数一起使用,该函数按位置定位子字符串并返回子字符串值。
  • 带有两个参数的 $LENGTH 根据分隔符返回字符串中子字符串的数量。此函数可与 $PIECE 函数一起使用,该函数通过分隔符定位子字符串并返回子字符串值。
  • $LENGTH 不应用于使用 $LISTBUILD$LIST 创建的编码列表。使用 $LISTLENGTH 确定编码列表字符串中的子字符串(列表元素)的数量。

$LENGTH$FIND$EXTRACT$PIECE 函数对标准字符串进行操作。各种 $LIST 函数对与标准字符串不兼容的编码字符串进行操作。唯一的例外是 $LISTGET 函数和 $LIST 的单参数和双参数形式,它们将编码字符串作为输入,但将单个元素值作为标准字符串输出。

0
0 222
文章 姚 鑫 · 三月 10, 2022 4m read

第七十七章 SQL函数 LENGTH

返回字符串表达式中字符数的字符串函数。

大纲

LENGTH(string-expression)

{fn LENGTH(string-expression)}

参数

  • string-expression - 字符串表达式,可以是列名、字符串文字或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(例如 CHARVARCHAR)。

LENGTH 返回 INTEGER 数据类型。

描述

LENGTH 返回一个整数,表示给定字符串表达式的字符数,而不是字节数。字符串表达式可以是字符串(从中删除尾随空格)或数字( IRIS 将其转换为规范形式)。

请注意,LENGTH 可用作 ODBC 标量函数(使用花括号语法)或 SQL 通用函数。

LENGTH 和其他长度函数($LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH)都执行以下操作:

  • LENGTH 返回字段的逻辑(内部数据存储)值的长度,而不是显示值,无论 SelectMode 设置如何。所有 SQL 函数始终使用字段的内部存储值。
  • LENGTH 返回数字的规范形式的长度。规范形式的数字不包括前导零和尾随零、前导符号(单个减号除外)和尾随小数分隔符。 LENGTH 返回数字字符串的字符串长度。数字字符串不会转换为规范形式。
  • LENGTH 不排除字符串中的前导空格。可以使用 LTRIM 函数从字符串中删除前导空格。

在执行以下操作时,LENGTH 与其他长度函数($LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH)不同:

  • LENGTH 不包括尾随空格和字符串终止字符。

$LENGTHCHARACTER_LENGTHCHAR_LENGTHDATALENGTH 不排除尾随空格和终止符。

  • 如果传递一个 NULL 值,LENGTH 返回 NULL,如果传递一个空字符串,则返回 0

如果传递 NULL 值,CHARACTER_LENGTHCHAR_LENGTHDATALENGTH 也返回 NULL,如果传递空字符串,则返回 0。如果传递一个 NULL 值,则 $LENGTH 返回 0,如果传递一个空字符串,则返回 0

  • LENGTH 不支持数据流字段。为字符串表达式指定流字段会导致 SQLCODE -37

$LENGTH 也不支持流字段。 CHARACTER_LENGTHCHAR_LENGTHDATALENGTH 函数确实支持数据流字段。

示例

在以下示例中, IRIS 首先将每个数字转换为规范形式(删除前导零和尾随零,解析前导符号,并删除尾随小数分隔符)。每个 LENGTH 返回长度为 1

SELECT {fn LENGTH(7.00)} AS CharCount,
       {fn LENGTH(+007)} AS CharCount,
       {fn LENGTH(007.)} AS CharCount,
       {fn LENGTH(00000.00)} AS CharCount,
       {fn LENGTH(-0)} AS CharCount
       
1	1	1	1	1

在以下示例中,第一个 LENGTH 删除前导零,返回长度值 2;第二个 LENGTH 将数值视为字符串,并且不删除前导零,返回长度值 3

SELECT LENGTH(0.7) AS CharCount,
       LENGTH('0.7') AS CharCount
       
2	3

以下示例返回值 12

SELECT LENGTH('INTERSYSTEMS') AS CharCount


12

以下示例显示了 LENGTH 如何处理前导和尾随空格。第一个 LENGTH 返回 15,因为 LENGTH 不包括尾随空格,但不包括前导空格。第二个 LENGTH 返回 12,因为 LTRIM 排除了前导空格:

SELECT LENGTH('   INTERSYSTEMS      ') AS CharCount,
       LENGTH(LTRIM('   INTERSYSTEMS      ')) AS CharCount
       
15	12

以下示例返回 Sample.Person 表中每个 Name 值中的字符数:

SELECT Name,{fn LENGTH(Name)} AS CharCount
FROM Sample.Person
ORDER BY CharCount

以下示例返回 DOB(出生日期)字段中的字符数。请注意,返回的长度(由 LENGTHCHAR_LENGTHCHARACTER_LENGTH)是日期的内部 ($HOROLOG) 格式,而不是显示格式。 DOB的显示长度为十个字符;所有三个长度函数都返回 5 的内部长度:

SELECT DOB,{fn LENGTH(DOB)} AS LenCount,
CHAR_LENGTH(DOB) AS CCount,
CHARACTER_LENGTH(DOB) AS CtrCount
FROM Sample.Person

以下嵌入式 SQL 示例给出了 Unicode 字符字符串的长度。返回的长度是字符数 (7),而不是字节数。

/// d ##class(PHA.TEST.SQLCommand).Length()
ClassMethod Length()
{
	s a = $CHAR(920,913,923,913,931,931,913)
	&sql(SELECT LENGTH(:a) INTO :b )
	if SQLCODE'=0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"The Greek Sea: ",a,!,$LENGTH(a),!,b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Length()
 
The Greek Sea: ΘΑΛΑΣΣΑ
7
7
0
0 89
文章 姚 鑫 · 三月 9, 2022 1m read

第七十六章 SQL函数 LEN

返回字符串表达式中字符数的字符串函数。

大纲

LEN(string-expression)

参数

  • string-expression - 字符串表达式,可以是列名、字符串文字或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(例如 CHARVARCHAR)。

LEN 返回 INTEGER 数据类型。

描述

注意:LEN 函数是 LENGTH 函数的别名。

SELECT len("yaoxin")  

6
0
0 96
文章 姚 鑫 · 三月 8, 2022 2m read

第七十五章 SQL函数 LEFT

标量字符串函数,返回从字符串表达式的开始(最左位置)开始的指定数量的字符。

大纲

{fn LEFT(string-expression,count)}

参数

  • string-expression - 字符串表达式,它可以是列的名称、字符串字面值或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(如CHARVARCHAR)。
  • count - 整数,指定从字符串表达式的起始位置返回的字符数。

描述

LEFT返回从字符串开始的指定字符数。 LEFT不填充字符串; 如果指定的字符数大于字符串中的字符数,则LEFT返回该字符串。 如果传递给任何一个参数一个NULL值,左返回NULL

LEFT只能用作ODBC标量函数(使用花括号语法)。

示例

以下示例返回 Sample.Person 表中每个名称的最左边的七个字符:

SELECT Name,{fn LEFT(Name,7)}AS ShortName
     FROM Sample.Person

以下嵌入式 SQL 示例显示了 LEFT 如何处理比字符串本身长的计数:

/// d ##class(PHA.TEST.SQLCommand).Left()
ClassMethod Left()
{
	&sql(
		SELECT Name,{fn LEFT(Name,40)}
		INTO :a,:b
		FROM Sample.Person
	)
	if SQLCODE'=0 {
		w !,"Error code ",SQLCODE 	
	} else {
		w !,a,"=original",!,b,"=LEFT 40" }
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Left()
 
Adams,Diane F.=original
Adams,Diane F.=LEFT 40
0
0 97
文章 姚 鑫 · 三月 7, 2022 3m read

第七十四章 SQL函数 LEAST

从一系列表达式中返回最小值的函数。

大纲

LEAST(expression,expression[,...])

参数

  • expression - 解析为数字或字符串的表达式。 将这些表达式的值相互比较,并返回最小值。 表达式可以是字段名、文字、算术表达式、主机变量或对象引用。 最多可以列出140个逗号分隔的表达式。

描述

LEAST从逗号分隔的表达式序列中返回最小值。 表达式按从左到右的顺序求值。 如果只提供一个表达式,则LEAST返回该值。 如果任何表达式为NULL, LEAST返回NULL

如果所有表达式值都解析为规范数,则按数值顺序对它们进行比较。 如果引用的字符串包含规范格式的数字,则按数字顺序对其进行比较。 但是,如果引用的字符串包含非规范格式的数字(例如,'00''0.4''+4'),则将其作为字符串进行比较。 字符串比较按排序顺序逐字符执行。 任何字符串值都大于任何数字值。

空字符串大于任何数字值,但小于任何其他字符串值。

如果返回值是一个数字,LEAST将以规范格式返回它(删除前导和末尾的零,等等)。 如果返回值是一个字符串,LEAST将不改变返回值,包括任何开头或结尾的空格。

LEAST返回逗号分隔的一系列表达式中的最小值。 GREATEST返回逗号分隔的一系列表达式中的最大值。 COALESCE返回逗号分隔的一系列表达式中的第一个非null值。

返回值数据类型

如果表达式值的数据类型不同,则返回的数据类型是与所有可能的返回值最兼容的类型,具有最高数据类型优先级的数据类型。 例如,如果一个表达式是整数,而另一个表达式是小数,则LEAST返回数据类型NUMERIC的值。 这是因为NUMERIC是具有最高优先级的数据类型,并且与两者兼容。 但是,如果表达式是文字数字或字符串,则LEAST返回数据类型VARCHAR

示例

在下面的例子中,每个LEAST比较三个正则数:

SELECT LEAST(22,2.2,-21) AS HighNum,
       LEAST('2.2','22','-21') AS HighNumStr
       
-21	-21

在下面的例子中,每个LEAST比较三个数字字符串。 然而,每个LEAST包含一个非规范字符串; 这些非规范值将作为字符串进行比较。 字符串总是大于数字:

SELECT LEAST('22','+2.2','21'),
       LEAST('0.2','22','21')
       
21	21

在下面的例子中,每个LEAST都会比较三个字符串,并返回排序序列最低的值:

SELECT LEAST('A','a',''),
       LEAST('a','aa','abc'),
       LEAST('#','0','7'),
       LEAST('##','00','77')
       
	a	0	77

下面的例子比较了两个被视为标准数字的日期:作为$HOROLOG整数的出生日期和转换为日期的58074整数。 它返回每个在20世纪出生的人的出生日期。 任何在1999年12月31日之后出生的人都会显示默认的出生日期为2000年1月1日:

SELECT Name,LEAST(DOB,TO_DATE(58074)) AS NewMillenium
FROM Sample.Person

image

0
0 81
文章 姚 鑫 · 三月 6, 2022 2m read

第七十三章 SQL函数 LCASE

将字符串中的所有大写字母转换为小写字母的大小写转换函数。

大纲

LCASE(string-expression)

{fn LCASE(string-expression)}

参数

  • string-expression - 要将其字符转换为小写的字符串表达式。表达式可以是列名、字符串文字或另一个标量函数的结果,其中底层数据类型可以表示为任何字符类型(如CHARVARCHAR)。

描述

LCASE将大写字母转换为小写字母用于显示。 它对非字母字符没有影响。 它保留没有改变的标点符号以及前导和末尾的空格。

LCASE不强制将数字解释为字符串。 SQL将数字转换为规范形式,删除前导和后导零。 SQL不将数字字符串转换为规范形式。

LOWER函数也可以用来将大写字母转换为小写字母。

LCASE不影响排序。 对于不区分大小写的排序规则,%SQLUPPER函数是SQL中转换数据值的首选方法。

示例

下面的例子以小写字母返回每个人的名字:

SELECT TOP 10 Name,{fn LCASE(Name)} AS LowName
     FROM Sample.Person

LCASE也适用于Unicode(非ascii)字母字符,如下面的嵌入式SQL示例所示,它将希腊字母从大写转换为小写:

/// d ##class(PHA.TEST.SQLCommand).LCase()
ClassMethod LCase()
{
	s a = $CHAR(920,913,923,913,931,931,913)
	&sql(
		SELECT LCASE(:a) INTO :b 
	)
	if SQLCODE'=0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,a,!,b 
	}
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).LCase()
 
ΘΑΛΑΣΣΑ
θαλασσα
0
0 147
文章 姚 鑫 · 三月 5, 2022 2m read

第七十二章 SQL函数 LAST_IDENTITY

返回最后插入、更新、删除或读取的行的标识的标量函数。

大纲

LAST_IDENTITY()

描述

LAST_IDENTITY函数返回%ROWID局部变量值。在嵌入式SQLODBC中将%ROWID局部变量设置为一个值。动态SQL、SQL Shell或管理门户SQL界面未将%ROWID局部变量设置为值。动态SQL改为设置%ROWID对象属性。

LAST_IDENTITY函数不接受任何参数。请注意,参数括号是必需的。

LAST_IDENTITY返回受当前进程影响的最后一行的标识字段值。如果表没有标识字段,则返回受当前进程影响的最后一行的行ID(%ROWID)。返回值为数据类型INTEGER

  • 对于嵌入式SQL INSERTUPDATEDELETETRUNCATE TABLE语句,LAST_IDENTITY返回最后修改的行的IDENTITY%ROWID值。
  • 对于嵌入式SQL基于游标的SELECT语句,LAST_IDENTITY返回检索到的最后一行的IDENTITY%ROWID值。但是,如果基于游标的SELECT语句包括DISTINCT关键字或GROUP BY子句,则LAST_IDENTITY不会更改;它将返回其先前的值(如果有)。
  • 对于嵌入式SQL单行(非游标)SELECT语句,LAST_IDENTITY不会更改。返回先前的值(如果有)。

在进程启动时,LAST_IDENTITY返回NULL。在新的%RowID之后,LAST_IDENTITY返回NULL

如果没有行受操作影响,则LAST_IDENTITY不会更改;LAST_IDENTITY返回其先前的值(如果有)。在新的%RowID之后,调用LAST_IDENTITY返回NULL,但调用%ROWID会生<UNDEFINED>错误。

示例

以下示例使用两个嵌入式SQL程序返回LAST_IDENTITY。第一个示例创建一个新表Sample.Students,第二个示例使用数据填充该表,然后对数据执行基于游标的SELECT,并为每个操作返回LAST_IDENTITY

请按显示的顺序运行这两个嵌入式SQL程序。(这里有必要使用两个嵌入式SQL程序,因为除非引用的表已经存在,否则嵌入式SQL无法编译INSERT语句。)

/// d ##class(PHA.TEST.SQLCommand).LastIdentity()
ClassMethod LastIdentity()
{
	w !,"Creating table"
	&sql(
		CREATE TABLE Sample.Students 
		(
			StudentName VARCHAR(30),
			StudentAge INTEGER,
			StudentID IDENTITY
		)
	)
	if SQLCODE=0 {
		w !,"Created table, SQLCODE=",SQLCODE }
	elseif SQLCODE=-201 {
		w !,"Table already exists, SQLCODE=",SQLCODE }
}

ClassMethod LastIdentity1()
{
	w !,"填充表"
	n %ROWCOUNT,%ROWID
	&sql(
		INSERT INTO Sample.Students 
		(
			StudentName, StudentAge
		)
		SELECT Name,Age FROM Sample.Person WHERE Age <= '21'
	)
	if SQLCODE = 0 {
		w !,%ROWCOUNT," 已添加记录,最后一行ID为 ",%ROWID,! 
	} else {
		w !,"Insert failed, SQLCODE=",SQLCODE 
	}
	&sql(
		SELECT LAST_IDENTITY()
		INTO :insertID
		FROM Sample.Students
	)
	w !,"插入最后一个ID为: ",insertID,!!
	/* 基于游标的SELECT查询 */
	&sql(
		DECLARE C10 CURSOR FOR 
		SELECT StudentName INTO :name FROM  Sample.Students
		WHERE StudentAge = '17'
	)
	&sql(OPEN C10)
	q:(SQLCODE'=0)
	&sql(FETCH C10)
	while (SQLCODE = 0) {
		w name," is seventeen",!
		&sql(FETCH C10) 
	}
	&sql(CLOSE C10)
	w !,%ROWCOUNT," 查询的记录,最后一行ID为 ",%ROWID,!
	&sql(SELECT LAST_IDENTITY()
	INTO :qId)
	w !,"SELECT Last Identity is: ",qId,!
	&sql(DROP TABLE Sample.Students)
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).LastIdentity1()
 
填充表
41 已添加记录,最后一行ID为 41
 
插入最后一个ID为: 41
 
Grabscheid,Jocelyn B. is seventeen
 
1 查询的记录,最后一行ID为 37
 
SELECT Last Identity is: 37
0
0 114
文章 姚 鑫 · 三月 4, 2022 2m read

第七十一章 SQL函数 LAST_DAY

日期函数,它为日期表达式返回一个月的最后一天的日期。

大纲

LAST_DAY(date-expression)

参数

  • date-expression - 表达式,它是列的名称、另一个标量函数的结果或日期或时间戳文字。

描述

LAST_DAY以整数形式返回指定月份的最后一天,格式为$HOROLOG。 计算闰年差异,包括世纪日调整:2000是闰年,19002100不是闰年。

日期表达式可以是一个日期整数、一个$HOROLOG$ZTIMESTAMP值、一个ODBC格式的日期字符串或一个时间戳。

日期表达式时间戳可以是数据类型%Library.PosiTime(编码的64位有符号整数)或数据类型%Library.TimeStamp(yyyy-mm-dd hh:mm:ss.fff)

%TIMESTAMP字符串的时间部分是可选的。

指定无效日期时,LAST_DAY返回0(显示模式为12/31/1840):日或月为零;大于12的月;或大于当年该月天数的日。年份必须在00019999之间。

也可以使用lastday()方法调用从ObjectScript调用此函数:

  WRITE $SYSTEM.SQL.Functions.LASTDAY("2018-02-22"),!
  WRITE $SYSTEM.SQL.Functions.LASTDAY(64701)

示例

以下示例将该月的最后一天作为日期整数返回。该值是显示为整数还是日期字符串取决于当前的SQL显示模式设置。

以下两个示例都返回数字59594(对应于‘2004-02-29’),因为指定日期的月份的最后一天是2月29(2004年是闰年):

SELECT LAST_DAY('2004-02-25')

2004/2/29 0:00:00
SELECT LAST_DAY(59590)

2004/2/29 0:00:00

以下示例均返回与当月最后一天对应的日期整数:

SELECT LAST_DAY({fn NOW()}) AS LD_Now,
       LAST_DAY(CURRENT_DATE) AS LD_CurrDate,
       LAST_DAY(CURRENT_TIMESTAMP) AS LD_CurrTstamp,
       LAST_DAY($ZTIMESTAMP) AS LD_ZTstamp,
       LAST_DAY($HOROLOG) AS LD_Horolog
       
2022/2/28 0:00:00	2022/2/28 0:00:00	2022/2/28 0:00:00	2022/2/28 0:00:00	2022/2/28 0:00:00
0
0 103
文章 姚 鑫 · 三月 3, 2022 4m read

第七十章 SQL函数 $JUSTIFY

在指定宽度内右对齐值的函数,可以选择舍入到指定的小数位数。

大纲

$JUSTIFY(expression,width[,decimal])

参数

  • expression - 要右对齐的值。它可以是数字值、字符串文字或解析为数字或字符串的表达式。
  • width - 表达式要在其中右对齐的字符数。正整数或计算结果为正整数的表达式。
  • decimal - 可选-小数位数。正整数或计算结果为正整数的表达式。将表达式中的小数位数四舍五入或填充到此值。如果指定DECIMAL,会将表达式视为数字。

描述

$JUSTIFY返回在指定宽度内右对齐的表达式指定的值。可以包括小数参数以在宽度内小数对齐数字。

  • $JUSTUST(expression,width):双参数语法在宽度内右对齐表达式。它不执行任何表达式转换。该表达式可以是数字字符串,也可以是非数字字符串。
  • $JUSTUST(expression,width,decimal):3参数语法将表达式转换为规范数字,将小数位四舍五入或零填充为小数,然后在宽度内右对齐生成的数值。如果表达式是非数字字符串或NULL,会将其转换为0,填充,然后右对齐。

$JUSTIFY识别当前区域设置的DecimalSeparator字符。 它根据需要添加或删除DecimalSeparator字符。 DecimalSeparator字符取决于区域设置; 通常,美式格式的语言环境使用句号(.),欧式格式的语言环境使用逗号()。 要为区域设置确定DecimalSeparator字符,请调用以下方法:

  WRITE ##class(%SYS.NLS.Format).GetFormatItem("DecimalSeparator")

如果指定的参数太少,就会发出SQLCODE -380。 如果指定的参数太多,就会发出SQLCODE -381

$JUSTIFY, ROUND和TRUNCATE

当舍入到固定数目的小数位数非常重要时(例如,表示货币金额时),请使用$JUSTIFY,它将返回舍入操作后指定数目的尾随零。 当decimal大于表达式中的小数位数时,$JUSTIFY的零位数。 $JUSTIFY也右对齐数字,使DecimalSeparator字符在一列数字中对齐。

ROUND也舍入指定数目的小数位数,但它的返回值总是规范化的,并删除后面的零。 例如,ROUND(10.004,2)返回10,而不是10.00。 与$JUSTIFY不同,ROUND允许指定舍入(默认值)或截断。

TRUNCATE截断指定的小数位数。 与ROUND不同的是,如果截断的结果是尾随的零,那么这些尾随的零将被保留。 然而,与$JUSTIFY不同的是,TRUNCATE不填零。

ROUNDTRUNCATE允许舍入(或截断)到小数分隔符的左边。 例如,ROUND(128.5,-1)返回130。

$JUSTIFY and LPAD

LPAD的双参数形式和$JUSTIFY的双参数形式都通过用前导空格填充字符串来对字符串进行右对齐。 这两个参数形式的不同之处是它们如何处理小于输入表达式长度的输出宽度:LPAD截断输入字符串以适应指定的输出长度。 $JUSTIFY扩展输出长度以适应输入字符串。 如下示例所示:

SELECT '>'||LPAD(12345,10)||'<' AS lpadplus,
       '>'||$JUSTIFY(12345,10)||'<' AS justifyplus,
       '>'||LPAD(12345,3)||'<' AS lpadminus,
       '>'||$JUSTIFY(12345,3)||'<' AS justifyminus

LPAD的三个参数形式允许使用空格以外的字符作为左pad。

参数

expression

右对齐的值,并可选地表示为具有指定小数位数的数字。

  • 如果需要字符串调整,请不要指定decimal。 表达式可以包含任意字符。 $JUSTIFY右对齐表达式,如width中所述。
  • 如果需要数字对齐,请指定decimal。 如果指定了decimal, 将表达式作为标准数字提供给$JUSTIFY。 它解决了前面的加减号,并删除了前面和后面的零。 它在第一个非数字字符处截断表达式。 如果表达式以非数字字符(例如货币符号)开头,则将表达式值转换为0。 规范转换不识别NumericGroupSeparator字符、货币符号、多个DecimalSeparator字符或尾随的加号或减号。

$JUSTIFY接收到正则数表达式后,$JUSTIFY执行其操作,将该正则数舍入或置零到小数位数的十进制数,然后右对齐结果,如width中所述。

width

要对转换后的表达式右对齐的宽度。 如果宽度大于表达式的长度(在数字和小数数字转换之后),将右对齐为宽度,并根据需要使用空白的左填充。 如果width小于表达式的长度(在数字和小数转换之后),将width设置为表达式值的长度。

将宽度指定为正整数。 宽度值为0、空字符串(")、NULL或非数字字符串将被视为宽度为0,这意味着将宽度设置为表达式值的长度。

decimal

小数位数的个数。 如果expression包含更多的小数位数,则$JUSTIFY将小数部分舍入为该小数位数。 如果表达式包含更少的小数位数,$JUSTIFY将小数部分用0填充到这个小数位数,并添加一个Decimal Separator字符(如果需要)。 如果decimal=0$JUSTIFY将表达式舍入为整数值并删除decimal Separator字符。

如果表达式值小于1,$JUSTIFY将在DecimalSeparator字符前插入前导零。

$DOUBLEINF-INFNAN不受十进制值的影响,由$JUSTIFY返回。

示例

下面的动态SQL示例对字符串执行右对齐。 不执行数值转换:

ClassMethod Justify()
{
	s myquery = "SELECT TOP 20 Age,$JUSTIFY(Name,18),DOB FROM Sample.Person"
	s tStatement = ##class(%SQL.Statement).%New()
	s qStatus = tStatement.%Prepare(myquery)
	s rset = tStatement.%Execute()
	d rset.%Display()
	w !,"End of data"
}

DHC-APP>d ##class(PHA.TEST.SQLCommand).Justify()
Age     Expression_2    DOB
31                  yaoxin      54536
                    xiaoli
8                       姚鑫    63189
8                       姚鑫    63189
44                      姚鑫    50066
                        姚鑫
                        姚鑫
         Isaacs,Roberta Z.
44      Chadwick,Zelda S.Chadwick,Zelda S.Chadwick,Zelda S.Chadwick,Zelda S.Chadwick,Zelda S.   50066
89          Fives,James D.      33527
48        Vonnegut,Jose P.      48488
94      Chadbourne,Barb B.      31690
74         Quigley,Barb A.      38960
8        O'Rielly,Chris H.      63189
79        Willeke,Alvin L.      37099
4           Orwell,John V.      64375

下面的动态SQL示例使用指定的小数位数执行数字右对齐:

/// d ##class(PHA.TEST.SQLCommand).Justify1()
ClassMethod Justify1()
{
	s myquery = 2
	s myquery(1) = "SELECT TOP 20 $JUSTIFY(Salary,10,2) AS FullSalary,"
	s myquery(2) = "$JUSTIFY(Salary/7,10,2) AS SeventhSalary FROM Sample.Employee"
	s tStatement = ##class(%SQL.Statement).%New()
	s qStatus = tStatement.%Prepare(.myquery)
	s rset = tStatement.%Execute()
	d rset.%Display()
	w !,"End of data"
}
DHC-APP>d ##class(PHA.TEST.SQLCommand).Justify1()
FullSalary      SeventhSalary
   2662.00          380.29
  21796.00         3113.71
  87539.00        12505.57
  53891.00         7698.71
  53682.00         7668.86
  50822.00         7260.29
  60625.00         8660.71
  49575.00         7082.14
  31914.00         4559.14
  49912.00         7130.29
  36968.00         5281.14
  85770.00        12252.86
  43806.00         6258.00
  19669.00         2809.86
  54810.00         7830.00
  21430.00         3061.43
  74680.00        10668.57
  28570.00         4081.43
  79082.00        11297.43
  58713.00         8387.57
 
20 Rows(s) Affected
End of data

下面的动态SQL示例对指定数量的小数进行数字右对齐,并对相同的数值进行字符串右对齐:

ClassMethod Justify2()
{
	s myquery = 2
	s myquery(1) = "SELECT $JUSTIFY({fn ACOS(-1)},8,3) AS ArcCos3,"
	s myquery(2) = "$JUSTIFY({fn ACOS(-1)},8) AS ArcCosAll"
	s tStatement = ##class(%SQL.Statement).%New()
	s qStatus = tStatement.%Prepare(.myquery)
	s rset = tStatement.%Execute()
	d rset.%Display()
}
DHC-APP> d ##class(PHA.TEST.SQLCommand).Justify2()
ArcCos3 ArcCosAll
   3.142        3.141592653589793238
 
1 Rows(s) Affected

下面的动态SQL示例使用$DOUBLEINFNAN执行数字右对齐:

ClassMethod Justify3()
{
	d ##class(%SYSTEM.Process).IEEEError(0)
	s x = $DOUBLE(1.2e500)
	s y = x - x
	s myquery = 2
	s myquery(1) = "SELECT $JUSTIFY(?,12,2) AS INFtest,"
	s myquery(2) = "$JUSTIFY(?,12,2) AS NANtest"
	s tStatement = ##class(%SQL.Statement).%New()
	s qStatus = tStatement.%Prepare(.myquery)
	s rset = tStatement.%Execute(x,y)
	d rset.%Display()
}
DHC-APP> d ##class(PHA.TEST.SQLCommand).Justify3()
INFtest NANtest
         INF             NAN
 
1 Rows(s) Affected
0
0 113
文章 姚 鑫 · 三月 1, 2022 8m read

第六十九章 SQL函数 JSON_OBJECT

将数据作为JSON对象返回的转换函数。

大纲

JSON_OBJECT(key:value [,key:value][,...] [NULL ON NULL | ABSENT ON NULL])

参数

  • key:value - 键:值对或逗号分隔的键:值对列表。键是由单引号分隔的用户指定的文字字符串。值可以是列名、聚合函数、算术表达式、数字或字符串文字或文字NULL
  • ABSENT ON NULLNULL ON NULL - 可选-指定如何在返回的JSON对象中表示空值的关键字短语。NULL ON NULL(缺省值)表示带有单词NULL(未引号)的NULL(缺少)数据。在NULL上缺失将从JSON对象中省略NULL数据;当valueNULL且不保留占位符逗号时,它将删除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会在值之前插入一个空格,因此通常最好指定大小写转换函数,如LCASEUCASE

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对象:

/// d ##class(PHA.TEST.SQLCommand).JsonObject()
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对象:

/// d ##class(PHA.TEST.SQLCommand).JsonObject1()
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对象:

/// d ##class(PHA.TEST.SQLCommand).JsonObject2()
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值的此选择模式:

/// d ##class(PHA.TEST.SQLCommand).JsonObject3()
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对象:

/// d ##class(PHA.TEST.SQLCommand).JsonObject4()
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测试:

/// d ##class(PHA.TEST.SQLCommand).JsonObject5()
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
0
0 164