0 关注者 · 478 帖子

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

文章 姚 鑫 · 四月 28, 2022 1m read

第126章 SQL函数 SIN

标量数值函数,返回角度的正弦值(以弧度为单位)。

大纲

{fn SIN(numeric-expression)}

参数

  • numeric-expression - 数值表达式。这是一个以弧度表示的角度。

SIN 返回 NUMERICDOUBLE 数据类型。如果 numeric-expression 是数据类型 DOUBLE,则 SIN 返回 DOUBLE;否则,它返回 NUMERIC

描述

SIN 接受任何数值并将其正弦作为浮点数返回。如果传递一个 NULL 值,SIN 返回 NULLSIN 将非数字字符串视为数值 0

SIN 返回一个精度为 19、小数位数为 18 的值。

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

可以使用 DEGREES 函数将弧度转换为度数。可以使用 RADIANS 函数将度数转换为弧度。

示例

以下示例显示了 SIN 的效果:

SELECT {fn SIN(0.52)} AS Sine

0.496880137843736714
0
0 75
文章 姚 鑫 · 四月 27, 2022 1m read

第125章 SQL函数 SIGN

返回给定数值表达式符号的数值函数。

大纲

SIGN(numeric-expression)

{fn SIGN(numeric-expression)}

参数

  • numeric-expression - 要为其返回符号的数字。

SIGN 返回 SMALLINT 数据类型。

描述

SIGN 返回以下内容:

  • -1 如果 numeric-expression 小于零。
  • 如果 numeric-expression 为零,则为 0(零):0+0-0
  • 如果 numeric-expression 大于零,则为 1
  • 如果 numeric-expressionNULL,或者它是非数字字符串,则为 NULL

SIGN 可用作 ODBC 标量函数(使用花括号语法)或 SQL 通用函数。

SIGN 在确定其值之前将数值表达式转换为规范形式。例如,SIGN(-+-+3)SIGN(-3+5) 都返回 1,表示一个正数。

注意:两个负号(连字符)是内嵌注释指示符。因此,指定两个连续负号的 SIGN 参数必须显示为用引号括起来的数字字符串。

示例

以下示例显示了 SIGN 的效果:

SELECT SIGN(-49) AS PosNeg

-1
SELECT {fn SIGN(-0.0)} AS PosNeg

0
SELECT SIGN(-+-16.748) AS PosNeg

1
SELECT {fn SIGN(NULL)} AS PosNeg

NULL
0
0 96
文章 姚 鑫 · 四月 26, 2022 4m read

第124章 SQL函数 SECOND

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

大纲

{fn SECOND(time-expression)}

参数

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

描述

SECOND 返回一个从 059 的整数,也可能返回小数秒。秒数是针对 $HOROLOG$ZTIMESTAMP 值、ODBC 格式日期字符串(没有时间值)或时间戳计算的。

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

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

必须提供时间戳字符串 (yyyy-mm-dd hh:mm:ss) 或 $HOROLOG 字符串。 $HOROLOG 字符串可以是完整的日期时间字符串 (63274,37279) 或只是 $HOROLOG (37279) 的时间整数部分。不能提供时间字符串 (hh:mm:ss);无论实际秒数如何,这始终返回 0

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

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

当秒部分为“0”“00”时,SECOND 返回 0 秒。如果提供了没有时间表达式的 ODBC 日期,或者完全省略了时间表达式的秒部分('hh', 'hh:mm', 'hh:mm:', or 'hh::')。

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

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

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

小数秒

如果在 time-expression 中提供 SECOND,则返回秒的小数部分。尾随零被截断。如果未指定小数秒(例如:38.00),则小数分隔符也会被截断。

时间值的标准内部表示 ($HOROLOG) 不支持小数秒。时间戳确实支持小数秒。

以下 SQL 函数支持小数秒:SECONDCURRENT_TIMESTAMPDATENAMEDATEPARTGETDATECURTIME、CURRENT_TIMENOW 不支持小数秒。

SQL SET OPTION 语句允许设置小数秒的默认精度(小数位数)。

ObjectScript $ZTIMESTAMP 特殊变量可用于表示小数秒。 ObjectScript 函数 $ZDATETIME$ZDATETIMEH$ZTIME$ZTIMEH 支持小数秒。

示例

以下示例都返回数字 38,因为它是时间表达式的 38 秒:

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

38
SELECT {fn SECOND(67538)} AS HorologSeconds

38

以下示例返回 0.9 秒。前导零和尾随零被截断:

SELECT {fn SECOND('2018-02-16 18:45:00.9000')} AS Seconds_Given

0

以下示例返回 0 秒,因为省略了日期时间字符串的秒部分:

SELECT {fn SECOND('2018-02-16 18:45')} AS Seconds_Given

0

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

SELECT {fn SECOND('2018-02-16')} AS Seconds_Given

0

以下示例均返回当前时间的秒部分,以整秒为单位:

SELECT {fn SECOND(CURRENT_TIME)} AS Sec_CurrentT,
       {fn SECOND({fn CURTIME()})} AS Sec_CurT,
       {fn SECOND({fn NOW()})} AS Sec_Now,
       {fn SECOND($HOROLOG)} AS Sec_Horolog,
       {fn SECOND($ZTIMESTAMP)} AS Sec_ZTS
       
40	40	40	40	40

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

SELECT LENGTH({fn SECOND('2018-02-15 11:45:22')}),
       LENGTH({fn SECOND('2018-02-15 03:05:06')}),
       LENGTH({fn SECOND('2018-02-15 3:5:6')}),
       LENGTH({fn SECOND('2018-02-15')})
       
2	1	1	1

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

/// d ##class(PHA.TEST.SQLFunction).Second()
ClassMethod Second()
{
	d ##class(%SYS.NLS.Format).SetFormatItem("TimeSeparator",".")
	&sql(
		SELECT {fn SECOND('2018-02-16 18.45.38')} INTO :a
	)
	w "seconds=",a
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Second()
seconds=38
0
0 168
文章 姚 鑫 · 四月 25, 2022 2m read

第123章 SQL函数 SEARCH_INDEX

从索引的 Find() 方法返回一组值的函数。

大纲

SEARCH_INDEX([[schema_name.]table-name.]index-name[,findparam[,...])

参数

  • table-name - 可选 — 为其定义了 index-name 的现有表的名称。不能是一个视图。表的 schema_name 是可选的。如果省略,则搜索 FROM 子句中指定的所有表。
  • index-name - 要搜索的索引。现有索引的索引映射的 SqlName
  • findparam - 可选 — 要传递给索引的 Find() 方法的参数或逗号分隔的参数列表。

描述

SEARCH_INDEX 调用 index-nameFind() 方法并返回一组值。可以选择将参数传递给此 Find() 方法。例如,SEARCH_INDEX(Sample.Person.NameIDX) 调用 Sample.Person.NameIDXFind() 方法。

SEARCH_INDEX 可以与 WHERE 子句中的 %FIND 谓词一起使用,以提供对象的 oref,该对象提供封装一组值的抽象表示。这些值通常是查询运行时调用的方法返回的行 IDSEARCH_INDEX 调用索引的 Find() 方法来返回这个 oref。此用法显示在以下示例中:

SELECT Name FROM Sample.Person AS P
WHERE P.Name %FIND SEARCH_INDEX(Sample.Person.NameIDX) 

该索引必须在 SQL 语句引用的表中找到。如果 SQL 语句使用的表中不存在指定的索引名称,则会生成 SQLCODE -151 错误。如果指定的索引名不是完全限定的,则会生成 SQLCODE -152 错误,因此在 SQL 语句使用的表中不明确(可能引用多个现有索引)。

如果索引存在,但没有对应的 Find() 方法,则生成运行时 SQLCODE -149 错误“SQL 函数遇到错误”,错误为 &<METHOD DOES NOT EXIST>

0
0 102
文章 姚 鑫 · 四月 24, 2022 2m read

第122章 SQL函数 RTRIM

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

大纲

RTRIM(string-expression)

{fn RTRIM(string-expression)}

参数

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

描述

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

无论要裁剪的输入表达式的数据类型是什么,RTRIM总是返回数据类型VARCHAR

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

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

示例

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

/// d ##class(PHA.TEST.SQLFunction).Rtrim()
ClassMethod Rtrim()
{
	s a="     Test string with 5 leading and 5 trailing spaces.     "
	&sql(
		SELECT {fn RTRIM(:a)} INTO :b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"Before RTRIM",!,"start:",a,":end"
		w !,"After RTRIM",!,"start:",b,":end" 
	}
}
Before RTRIM
start:     Test string with 5 leading and 5 trailing spaces.     :end
After RTRIM
start:     Test string with 5 leading and 5 trailing spaces.:end
0
0 126
文章 姚 鑫 · 四月 23, 2022 2m read

第121章 SQL函数 RPAD

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

大纲

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

参数

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

描述

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

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

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

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

示例

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

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

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

SELECT TOP 15 Name,RPAD(Name,20,'^=^') AS Name20
   FROM Sample.Person 
0
0 153
文章 姚 鑫 · 四月 22, 2022 5m read

第120章 SQL函数 ROUND

以指定位数舍入或截断数字的数值函数。

大纲

ROUND(numeric-expr,scale[,flag])

{fn ROUND(numeric-expr,scale[,flag])}

参数

  • numeric-expr - 要四舍五入的数字。一个数值表达式。
  • scale - 计算结果为整数的表达式,该整数指定要舍入到的位数,从小数点开始计数。可以是零、正整数或负整数。如果 scale 是小数, 会将其四舍五入为最接近的整数。
  • flag - 可选 — 一个布尔标志,指定是舍入还是截断 numeric-expr:0=round, 1=truncate。默认值为 0

ROUND 返回与 numeric-expr 相同的数据类型。

描述

此函数可用于将数字舍入或截断为指定的小数位数。

ROUNDnumeric-expr 舍入或截断以缩放位置,从小数点开始计数。舍入时,数字 5 始终向上舍入。在 ROUND 循环或截断操作后删除尾随零。不返回前导零。

  • 如果 scale 为正数,则在小数点右侧的该位数处进行舍入。如果 scale 等于或大于小数位数,则不会发生舍入或零填充。
  • 如果 scale 为零,则舍入到最接近的整数。换句话说,在小数点右边的零位处进行舍入;所有小数位和小数点本身都被删除。
  • 如果 scale 为负数,则在小数点左侧的该位数处进行舍入。如果 scale 等于或大于舍入结果中的整数位数,则返回零。
  • 如果 numeric-expr 为零(但表示为:00.00-0 等),ROUND 将返回 0(零)且没有小数位,而不管比例值如何。
  • 如果 numeric-exprscaleNULLROUND 返回 NULL

请注意,ROUND 返回值始终是标准化的,删除尾随零。

ROUND、TRUNCATE 和 $JUSTIFY

ROUNDTRUNCATE 是执行类似操作的数值函数;它们都可用于减少数字的有效小数位数或整数位数。 ROUND 允许指定舍入(默认)或截断; TRUNCATE 不执行舍入。 ROUND 返回与 numeric-expr 相同的数据类型; TRUNCATE 返回 numeric-expr 作为数据类型 NUMERIC,除非 numeric-expr 是数据类型 DOUBLE,在这种情况下它返回数据类型 DOUBLE

ROUND 舍入(或截断)到指定数量的小数位数,但其返回值始终是标准化的,删除尾随零。例如,ROUND(10.004,2) 返回 10,而不是 10.00

TRUNCATE 截断到指定数量的小数位数。如果截断导致尾随零,则保留这些尾随零。但是,如果 scale 大于 numeric-expr 规范形式的小数位数,则 TRUNCATE 不会填充零。

当舍入到固定的小数位数很重要时使用 $JUSTIFY - 例如,在表示货币金额时。 $JUSTIFY 在舍入操作之后返回指定数量的尾随零。当要舍入的位数大于小数位数时,$JUSTIFY 补零。 $JUSTIFY 还右对齐数字,以便 DecimalSeparator 字符在一列数字中对齐。 $JUSTIFY 不会截断。

$DOUBLE 数字

$DOUBLE IEEE 浮点数使用二进制表示法编码。大多数十进制分数不能用这种二进制表示法精确表示。当 $DOUBLE 值被输入到带有刻度值和舍入标志(flag = 0,默认值)的 ROUND 时,返回值通常包含比刻度中指定的更多的小数位数,因为小数位数的结果不能用二进制表示,所以返回值必须四舍五入到最接近的可表示的 $DOUBLE 值,如以下示例所示:

/// d ##class(PHA.TEST.SQLFunction).Round()
ClassMethod Round()
{
	s x = 1234.5678
	s y = $DOUBLE(1234.5678)
	&sql(SELECT ROUND(:x,2),ROUND(:y,2) INTO :decnum,:dblnum)
	w "Decimal: ",x," rounded ",decnum,!
	w "Double: ",y," rounded ",dblnum
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Round()
Decimal: 1234.5678 rounded 1234.57
Double: 1234.5678000000000338 rounded 1234.5699999999999363

如果使用 ROUND 截断 $DOUBLE 值(标志 = 1),则 $DOUBLE 的返回值将被截断为小数位数指定的小数位数。 TRUNCATE 函数还将 $DOUBLE 截断为由 scale 指定的小数位数。

如果使用 ROUND$DOUBLE 值进行舍入并希望返回特定的比例,则应在舍入结果之前将 $DOUBLE 值转换为十进制表示。

带有 flag=0ROUNDround,默认值)返回 $DOUBLE("INF")$DOUBLE("NAN") 作为空字符串。

如果使用 ROUND$DOUBLE 值进行舍入并希望返回特定的比例,则应在舍入结果之前将 $DOUBLE 值转换为十进制表示。

带有 flag=0ROUNDround,默认值)返回 $DOUBLE("INF")$DOUBLE("NAN") 作为空字符串。

带有 flag=1(截断)的 ROUND 返回 $DOUBLE("INF")$DOUBLE("NAN") 作为 INFNAN

示例

以下示例使用 0(零)的比例将多个分数舍入为整数。它表明 5 总是向上取整:

SELECT ROUND(5.99,0) AS RoundUp,
       ROUND(5.5,0) AS Round5,
       {fn ROUND(5.329,0)} AS Roundoff
       
6	6	5

以下示例截断与上一个示例相同的小数:

SELECT ROUND(5.99,0,1) AS Trunc1,
       ROUND(5.5,0,1) AS Trunc2,
       {fn ROUND(5.329,0,1)} AS Trunc3
       
5	5	5

以下 ROUND 函数对负小数进行舍入和截断:

SELECT ROUND(-0.987,2,0) AS Round1,
       ROUND(-0.987,2,1) AS Trunc1
       
-0.99	-0.98

以下示例将 pi 舍入为四位小数:

SELECT {fn PI()} AS ExactPi, ROUND({fn PI()},4) AS ApproxPi

3.141592653589793238	3.1416

以下示例指定了大于十进制位数的比例:

SELECT {fn ROUND(654.98700,9)} AS Rounded

654.987

它返回 654.987( 在舍入操作之前删除了尾随零;没有发生舍入或零填充)。

以下示例将 Salary 的值四舍五入到最接近的千美元:

SELECT Salary,ROUND(Salary, -3) AS PayBracket
FROM Sample.Employee
ORDER BY Salary

image

请注意,如果 Salary 小于 500 美元,则四舍五入为 0(零)。

在下面的示例中,每个 ROUND 都指定一个与要舍入的数字一样大或更大的负比例:

SELECT {fn ROUND(987,-3)} AS Round1,
       {fn ROUND(487,-3)} AS Round2,
       {fn ROUND(987,-4)} AS Round3,
       {fn ROUND(987,-5)} AS Round4
       
1000	0	0	0

第一个 ROUND 函数返回 1000,因为舍入结果的位数多于小数位数。其他三个 ROUND 函数返回 0(零)。

0
0 243
文章 Jiakeng Lei · 四月 22, 2022 1m read

问题: 通过JDBC连接Oracle19C数据报错 "ORA-28040: No matching authentication protocal"

解决 : 1、在数据库服务器上找到sqlnet.ora文件,一般在oracle安装目录app/oracle/product/19.0.0.0/db_1/network/admin/sqlnet.ora

2、如果有进行修改,没有直接创建

3、slqnet.ora文件新增或修改以下 SQLNET.ALLOWED_LOGON_VERSION_SERVER=8 SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8

4、注意事项: ① 如果没有sqlnet.ora文件可以直接创建 vi sqlnet.ora ② 如果有不能直接vi 需要使sed -a 命令追加,否则会导致ora文件乱码 ③ 添加参数后新无需重启数据库或者监听,但是需要修改用户密码,否则会报错

5、修改用户名密码

sqlplus / as sysdba

alter user 用户名 identified by 新密码;

2
0 326
文章 姚 鑫 · 四月 21, 2022 1m read

第119章 SQL函数 RIGHT

标量字符串函数,它从字符串表达式的末尾(最右边的位置)返回指定数量的字符。

大纲

{fn RIGHT(string-expression,count)}

参数

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

描述

RIGHT 从字符串表达式的末尾(最右边的位置)返回 count 个字符。如果为任一参数传递 NULL 值,RIGHT 将返回 NULL

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

示例

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

SELECT Name,{fn RIGHT(Name,2)}AS MiddleInitial
     FROM Sample.Person

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

/// d ##class(PHA.TEST.SQLFunction).Right()
ClassMethod Right()
{
	&sql(
		SELECT Name,{fn RIGHT(Name,40)}
			INTO :a,:b
		FROM Sample.Person
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,a,"=original",!,b,"=RIGHT 40" 
	}
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).Right()
 
Adams,Diane F.=original
Adams,Diane F.=RIGHT 40

不执行填充。

0
0 84
文章 姚 鑫 · 四月 20, 2022 2m read

第118章 SQL函数 REVERSE

标量字符串函数,它以相反的字符顺序返回一个字符串。

大纲

REVERSE(string-expression)

参数

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

描述

REVERSE 返回字符顺序颠倒的字符串表达式。例如 'Hello World!' 返回为 '!dlroW olleH'。这是一个简单的字符串顺序反转,没有额外的处理。

返回的字符串是数据类型 VARCHAR,与输入值的数据类型无关。数字转换为规范形式,数字字符串在反转之前不会转换为规范形式。

前导和尾随空白不受反转的影响。

反转 NULL 值会导致 NULL

注意:因为 REVERSE 总是返回一个 VARCHAR 字符串,所以某些类型的数据在反转时会变得无效:

  • 反向列表不再是有效列表,无法从存储格式转换为显示格式。
  • 反转日期不再是有效日期,并且无法从存储格式转换为显示格式。

示例

以下示例反转 Name 字段值。在这种情况下,这会导致名称按中间名首字母排序:

SELECT Name,REVERSE(Name) AS RevName
FROM Sample.Person
ORDER BY RevName

请注意,因为 NameRevName 只是同一字段的不同表示,所以 ORDER BY RevNameORDER BY RevName,Name 执行相同的排序。

以下示例反转数字和数字字符串:

SELECT REVERSE(+007.10) AS RevNum,
       REVERSE('+007.10') AS RevNumStr
       
1.7	01.700+

以下嵌入式 SQL 示例反转 $DOUBLE 数字:

/// d ##class(PHA.TEST.SQLFunction).Reverse()
ClassMethod Reverse()
{
	s dnum = $DOUBLE(1.1)
	&sql(
		SELECT REVERSE(:dnum) INTO :drevnum
	)
	w dnum,!
	w drevnum,!
}
DHC-APP> d ##class(PHA.TEST.SQLFunction).Reverse()
1.1000000000000000888
8880000000000000001.1

以下示例显示了反转列表时发生的情况:

SELECT FavoriteColors,REVERSE(FavoriteColors) AS RevColors
FROM Sample.Person

以下示例显示了反转日期时发生的情况:

SELECT DOB,%INTERNAL(DOB) AS IntDOB,REVERSE(DOB) AS RevDOB
FROM Sample.Person
0
0 114
文章 姚 鑫 · 四月 19, 2022 1m read

第117章 SQL函数 REPLICATE

将字符串重复指定次数的字符串函数。

大纲

REPLICATE(expression,repeat-count)

参数

  • expression - 要重复的字符串表达式。
  • repeat-count - 重复的次数,以整数表示。

描述

注意:REPLICATE 函数是 REPEAT 函数的别名。提供 REPLICATE 是为了与 TSQL 兼容。有关详细信息,请参阅重复。

0
0 71
文章 姚 鑫 · 四月 18, 2022 3m read

第116章 SQL函数 REPLACE

字符串函数,用于替换字符串中的子字符串。

大纲

REPLACE(string,oldsubstring,newsubstring)

参数

  • string - 作为子字符串搜索目标的字符串表达式。
  • oldsubstring - 字符串中要匹配的子字符串。
  • newsubstring - 用于替换 oldsubstring 的子字符串。

描述

REPLACE 在字符串中搜索子字符串并替换所有匹配项。匹配区分大小写。如果找到匹配项,它将用 newsubstring 替换 oldsubstring 的每个实例。替换子串可能比它替换的子串长或短。如果找不到子字符串,则 REPLACE 将原样返回原字符串。

无论字符串的数据类型如何,REPLACE 返回的值始终是数据类型 VARCHAR。这允许替换操作,例如 REPLACE(12.3,'.','_')

REPLACE 不能对字符串、oldsubstringnewsubstring 参数使用 %Stream.GlobalCharacter 字段。尝试这样做会生成 SQLCODE -37 错误。

空字符串是字符串值。因此,可以将空字符串用于任何参数值。但是,请注意 ObjectScript 空字符串作为 NULL 传递给 SQL

NULL 不是 SQL 中的数据值。因此,为任何 REPLACE 参数指定 NULL 将返回 NULL,无论是否发生匹配。

此函数提供与 Transact-SQL 实现的兼容性。

REPLACE, STUFF, and $TRANSLATE

REPLACESTUFF 都执行子字符串替换。 REPLACE 按数据值搜索子字符串。 STUFF 按字符串位置和长度搜索子字符串。

REPLACE 执行单个字符串对字符串的匹配和替换。 $TRANSLATE 执行逐字符匹配和替换;它可以用相应的指定替换单个字符替换一个或多个指定单个字符的所有实例。它还可以从字符串中删除一个或多个指定单个字符的所有实例。

默认情况下,所有三个函数都区分大小写并替换所有匹配的实例。

示例

以下示例搜索子字符串“P”的每个实例并将其替换为子字符串“K”

SELECT REPLACE('PING PONG','P','K')

KING KONG

以下嵌入式 SQL 示例搜索子字符串“KANSAS”的每个实例,并将其替换为子字符串“NEBRASKA”

/// d ##class(PHA.TEST.SQLFunction).Replace()
ClassMethod Replace()
{
	s str = "KANSAS, ARKANSAS, NEBRASKA"
	&sql(
		SELECT REPLACE(:str,'KANSAS','NEBRASKA') INTO :x
	)
	w !,"SQLCODE=",SQLCODE
	w !,"Output string=",x
}


DHC-APP>d ##class(PHA.TEST.SQLFunction).Replace()
SQLCODE=0
Output string=NEBRASKA, ARNEBRASKA, NEBRASKA

以下示例显示 REPLACE 处理空字符串 ('') 就像处理任何其他字符串值一样:

SELECT REPLACE('','','Nothing'),
       REPLACE('PING PONG','','K'),
       REPLACE('PING PONG','P','')
       
Nothing	PING PONG	ING ONG

以下示例显示 REPLACE 通过返回 NULL 来处理任何 NULL 参数。以下所有 REPLACE 函数都返回 NULL,包括最后一个,其中不发生匹配:

SELECT REPLACE(NULL,'K','P'),
       REPLACE(NULL,NULL,'P'),
       REPLACE('PING PONG',NULL,'K'),
       REPLACE('PING PONG','P',NULL),
       REPLACE('PING PONG','Z',NULL)
       
NULL NULL NULL NULL NULL				

以下嵌入式 SQL 示例与前面的 NULL 示例相同。它显示了如何在 SQL 中将 ObjectScript 空字符串主变量视为 NULL

/// d ##class(PHA.TEST.SQLFunction).Replace1()
ClassMethod Replace1()
{
	s a = ""
	&sql(
		SELECT 
			REPLACE(:a,'K','P'),
			REPLACE(:a,:a,'P'),
			REPLACE('PING PONG',:a,'K'),
			REPLACE('PING PONG','P',:a),
			REPLACE('PING PONG','Z',:a)
		INTO :v,:w,:x,:y,:z
	)
	w !,"SQLCODE=",SQLCODE
	w !,"Output string=",v
	w !,"Output string=",w
	w !,"Output string=",x
	w !,"Output string=",y
	w !,"Output string=",z
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Replace1()
 
SQLCODE=0
Output string=
Output string=
Output string=
Output string=
Output string=
0
0 153
文章 姚 鑫 · 四月 17, 2022 1m read

第115章 SQL函数 REPEAT

将字符串重复指定次数的字符串函数。

大纲

REPEAT(expression,repeat-count)

{fn REPEAT(expression,repeat-count)}

参数

  • expression - 要重复的字符串表达式。
  • repeat-count - 重复的次数,以整数表示。

描述

REPEAT 返回一串重复计数的表达式实例,连接在一起。

如果表达式为 NULL,则 REPEAT 返回 NULL。如果 expression 是空字符串,则 REPEAT 返回一个空字符串。

如果重复计数是小数,则仅使用整数部分。如果重复计数为 0,则 REPEAT 返回一个空字符串。如果重复计数是负数、NULL 或非数字字符串,则 REPEAT 返回 NULL

示例

以下示例显示了 REPEAT 的两种形式。两个示例都返回字符串“BANGBANGBANG”

SELECT REPEAT('BANG',3) AS Tripled

BANGBANGBANG
SELECT {fn REPEAT('BANG',3)} AS Tripled

BANGBANGBANG
0
0 132
文章 姚 鑫 · 四月 16, 2022 2m read

第114章 SQL函数 RADIANS

将度数转换为弧度的数值函数。

大纲

RADIANS(numeric-expression)

{fn RADIANS(numeric-expression)}

参数

  • numeric-expression - 以度为单位的角度度量。解析为数值的表达式。

RADIANS 返回 NUMERICDOUBLE 数据类型。如果 numeric-expression 是数据类型 DOUBLERADIANS 返回 DOUBLE;否则,它返回 NUMERIC

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

描述

RADIANS 以度为单位进行角度测量,并以弧度返回相应的角度测量。如果传递 NULL 值,RADIANS 将返回 NULL

返回值的默认精度为 36,默认小数位数为 18

可以使用 DEGREES 函数将弧度转换为度数。

示例

以下嵌入式 SQL 示例以 30 度为增量返回与从 0365 的度值对应的弧度等效值:

/// d ##class(PHA.TEST.SQLFunction).Radians()
ClassMethod Radians()
{
	s a = 0
	while a < 366 {
		&sql(
			SELECT RADIANS(:a) INTO :b
		)
		if SQLCODE '= 0 {
			w !,"Error code ",SQLCODE 
		} else {
		w !,"degrees ",a," = radians ",b
		s a = a + 30 
		}
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Radians()
 
degrees 0 = radians 0
degrees 30 = radians .5235987755982988731
degrees 60 = radians 1.047197551196597746
degrees 90 = radians 1.570796326794896619
degrees 120 = radians 2.094395102393195492
degrees 150 = radians 2.617993877991494366
degrees 180 = radians 3.141592653589793239
degrees 210 = radians 3.665191429188092112
degrees 240 = radians 4.188790204786390985
degrees 270 = radians 4.712388980384689858
degrees 300 = radians 5.235987755982988731
degrees 330 = radians 5.759586531581287604
degrees 360 = radians 6.283185307179586477
0
0 109
文章 姚 鑫 · 四月 15, 2022 2m read

第113章 SQL函数 QUARTER

日期函数,它将一年中的季度作为日期表达式的整数返回。

大纲

{fn QUARTER(date-expression)}

参数

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

描述

QUARTER 返回一个从 14 的整数。季度是针对 日期整数、$HOROLOG 或 $ZTIMESTAMP 值、ODBC 格式日期字符串或时间戳计算的。

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

四个季度的时间段如下:

QuarterPeriod (inclusive)
1January 1 to March 31 (90 or 91 days)
2April 1 to June 30 (91 days)
3July 1 to September 30 (92 days)
4October 1 to December 31 (92 days)

QUARTER 基于日期时间字符串的月份部分。但是,所有日期表达式都经过验证,并且必须包含 112 范围内的月份以及指定月份和年份的有效日期值。否则,将生成 SQLCODE -400 错误 <ILLEGAL VALUE> date-expression 的时间部分可以省略,但如果存在则必须有效。

使用 DATEPARTDATENAME 函数可以返回相同的季度信息。可以使用 DATEADDTIMESTAMPADD 函数将日期增加指定的季度数。

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

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

示例

以下示例均返回数字 1,因为日期(222 日)位于该年的第一季度:

SELECT {fn QUARTER('2018-02-22')} AS ODBCDateQ

1
SELECT {fn QUARTER(64701)} AS HorologDateQ

1

以下示例均返回当前季度:

SELECT {fn QUARTER({fn NOW()})} AS Q_Now,
       {fn QUARTER(CURRENT_DATE)} AS Q_CurrD,
       {fn QUARTER(CURRENT_TIMESTAMP)} AS Q_CurrTstamp,
       {fn QUARTER($ZTIMESTAMP)} AS Q_ZTstamp,
       {fn QUARTER($HOROLOG)} AS Q_Horolog
       
1
0
0 132
文章 姚 鑫 · 四月 13, 2022 1m read

第111章 SQL函数 PREDICT

IntegratedML 函数,它应用指定的训练模型来预测提供的每个输入行的结果。

大纲

PREDICT(model-name )

PREDICT(model-name USE trained-model-name )

PREDICT(model-name WITH feature-columns-clause )

PREDICT(model-name USE trained-model-name WITH feature-columns-clause )

描述

PREDICT 是一个 IntegratedML 函数,可用作 SELECT 选择项以返回将经过训练的机器学习模型应用于指定查询的结果。

0
0 98
文章 姚 鑫 · 四月 12, 2022 2m read

第110章 SQL函数 POWER

一个数值函数,它返回给定表达式的指定幂的值。

大纲

POWER(numeric-expression,power)

{fn POWER(numeric-expression,power)}

参数

  • numeric-expression - 基数。可以是正整数或负整数或小数。
  • power - 指数,它是数值表达式的幂。可以是正整数或负整数或小数。

POWER 返回 NUMERICDOUBLE 数据类型。如果 numeric-expression 是数据类型 DOUBLE,则 POWER 返回 DOUBLE;否则,它返回 NUMERIC

描述

POWER 计算一个数字的另一个幂。它返回一个精度为 36、比例为 18 的值。

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

numeric-expressionpower 的所有组合都是有效的,除了:

  • POWER(0,-m)0 数字表达式和负幂会导致 SQLCODE -400 错误。
  • POWER(-n,.m):负数值表达式和小数幂会导致 SQLCODE -400 错误。

示例

以下示例将 5 提高到 3 次方:

SELECT POWER(5,3) AS Cubed

125

以下嵌入式 SQL 示例返回 2 的前 16 次幂:

/// d ##class(PHA.TEST.SQLFunction).Power()
ClassMethod Power()
{
	s a = 1
	while a < 17 {
		&sql(
			SELECT {fn POWER(2, :a)}
				INTO :b
		)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"2 to the ",a," = ",b
		s a = a +1  }
	}
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).Power()
 
2 to the 1 = 2
2 to the 2 = 4
2 to the 3 = 8
2 to the 4 = 16
2 to the 5 = 32
2 to the 6 = 64
2 to the 7 = 128
2 to the 8 = 256
2 to the 9 = 512
2 to the 10 = 1024
2 to the 11 = 2048
2 to the 12 = 4096
2 to the 13 = 8192
2 to the 14 = 16384
2 to the 15 = 32768
2 to the 16 = 65536
0
0 112
文章 姚 鑫 · 四月 11, 2022 2m read

第109章 SQL函数 POSITION

返回子字符串在字符串中的位置的字符串函数。

大纲

POSITION(substring IN string)

参数

  • substring - 要搜索的子字符串。 它可以是列的名称、字符串字面值或另一个标量函数的结果,其中基础数据类型可以表示为任何字符类型(如CHARVARCHAR2)。
  • IN string - 要在其中搜索子字符串的字符串表达式。

POSITION返回INTEGER数据类型。

描述

POSITION返回字符串中子字符串的第一个位置。 位置以整数形式返回。 如果substring没有找到,则返回0(0)。 如果传递给任何一个参数一个NULL值,POSITION将返回NULL

位置是区分大小写的。 使用其中一个大小写转换函数来定位字母或字符串的大写和小写实例。

POSITION, INSTR, CHARINDEX和$FIND

POSITIONINSTRCHARINDEX$FIND都将搜索字符串中指定的子字符串,并返回与第一个匹配项对应的整数位置。 CHARINDEXPOSITIONINSTR返回匹配子字符串的第一个字符的整数位置。 $FIND返回匹配子字符串结束后第一个字符的整数位置。 CHARINDEX$FINDINSTR支持指定子字符串搜索的起始点。 INSTR还支持从起始点指定子字符串出现。

下面的示例演示了这四个函数,指定了所有可选参数。 注意,在这些函数中,stringsubstring的位置不同:

SELECT POSITION('br' IN 'The broken brown briefcase') AS Position,
       CHARINDEX('br','The broken brown briefcase',6) AS Charindex,
       $FIND('The broken brown briefcase','br',6) AS Find,
       INSTR('The broken brown briefcase','br',6,2) AS Inst
       
5	12	14	18

示例

下面的例子返回11,因为“b”是字符串中的第11个字符:

SELECT POSITION('b' IN 'The quick brown fox') AS PosInt

11

下面的示例返回示例中每个名字的姓氏长度。 人表。 它定位用于将姓氏与name字段的其余部分分隔开的逗号,然后从该位置减去1:

SELECT Name,
POSITION(',' IN Name)-1 AS LNameLen
FROM Sample.Person

下面的示例返回样本中每个名称中字母“B”的第一个实例的位置。 人表。 因为POSITION是区分大小写的,所以在执行搜索之前使用%SQLUPPER函数将所有的名称值转换为大写。 因为%SQLUPPER在字符串的开头添加了一个空格,所以这个示例减去1以获得实际的字母位置。 没有找到指定字符串的搜索将返回0 (0); 在本例中,由于减法为1,这些搜索显示的值为-1:

SELECT Name,
POSITION('B' IN %SQLUPPER(Name))-1 AS BPos
FROM Sample.Person
0
0 134
文章 姚 鑫 · 四月 10, 2022 2m read

[toc]

第108章 SQL函数 %PLUS

将数字转换为规范排序格式的排序函数。

大纲

%PLUS(expression)

%PLUS expression

参数

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

描述

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

数字可以包含前导和后导零、多个前导加减号、单个小数点指示符(.)和E指数指示符。 在标准形式中,将执行所有算术运算,展开指数,将符号解析为一个前导减号或无符号,并剥离前导和后导零。

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

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

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

  WRITE $SYSTEM.Util.Collation("++007.500",3)

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

示例

以下示例使用 %PLUS 按数字顺序返回 Home_Street 地址:

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

注意,上面的示例按照升序数字顺序对街道地址的整数部分进行排序。 将其与下面的ORDER BY示例进行比较,该示例按照排序顺序对街道地址进行排序:

SELECT Name,Home_Street
FROM Sample.Person
ORDER BY Home_Street
0
0 106
问题 Michael Lei · 四月 7, 2022

你好!

我想知道,如果在没有运行%BuildIndices()方法的情况下向表中插入索引,是否会有问题。

需要注意的是,在索引之前插入的数据对于检索来说并不重要,所以在索引之前插入的数据在查询中不显示并不是问题。

我问这个问题的原因是,我想避免在需要插入这种索引的大表中进行索引重建。

我正在使用Cache 2018.1。

谢谢。

José

Hi!

I'd like to know if there are any issues if an index is inserted into a table without running the %BuildIndices() method.

It's important to note that data inserted before the index is not important for retrieval, so it's not a problem data inserted before the index don't show up in queries.

The reason why I'm asking this is that I'd like to avoid index reconstruction on big tables which I need to inser such index.

2
0 230
文章 姚 鑫 · 四月 9, 2022 7m read

第107章 SQL函数 $PIECE

返回由分隔符标识的子字符串的字符串函数。

大纲

$PIECE(string-expression,delimiter[,from[,to]])

参数

  • string-expression - 要从中提取子字符串的目标字符串。 表达式,可以是字段名、字符串字面值、数字或其他函数的结果。
  • delimiter - 用于标识子字符串的分隔符。
  • from - 可选-指定要从目标字符串返回的子字符串或子字符串范围的开头的整数。 子字符串由分隔符分隔,从1开始计数。 如果省略,则返回第一个子字符串。
  • to - 可选-一个整数,指定从目标字符串返回的子字符串范围的结束子字符串。 必须与from连用。

描述

$PIECE从字符串表达式中返回指定的子字符串(PIECE)。 返回的子字符串取决于所使用的参数:

  • $PIECE(string-expression,delimiter)返回string-expression中的第一个子字符串。 如果delimiter出现在字符串表达式中,则这是在delimiter第一次出现之前的子字符串。 如果分隔符没有出现在字符串表达式中,则返回的子字符串为字符串表达式。
  • $PIECE(string-expression,delimiter,from)返回string-expression的第n个片段的子字符串,其中整数nfrom参数指定,片段由一个分隔符分隔。 分隔符不返回。
  • $PIECE(string-expression,delimiter,from,to)返回一个范围的子字符串,包括从中指定的子字符串到到中指定的子字符串。 $PIECE的这种4个参数形式返回一个字符串,其中包括在fromto子字符串之间出现的任何中间分隔符。 如果to大于子字符串的数量,则返回的子字符串包括到string-expression字符串结尾的所有子字符串。

参数

string-expression

要从其中返回子字符串的字符串。 它可以是字符串字面值、变量名或任何计算结果为字符串的有效表达式。

字符串通常包含用作分隔符的字符(或字符串)的实例。 此字符或字符串也不能用作字符串表达式中的数据值。

如果你指定空字符串(null)作为目标字符串,$PIECE返回<null>,空字符串。

delimiter

用于在字符串表达式中分隔子字符串的搜索字符串。 它可以是数字字面值或字符串字面值(用引号括起来)、变量名或计算结果为字符串的表达式。

通常,分隔符是一个指定的字符,它永远不会在字符串数据中使用,但仅用于作为分隔子字符串的分隔符使用。 分隔符也可以是多字符搜索字符串,其中的单个字符可以在字符串数据中使用。

如果指定空字符串(null)作为分隔符,$PIECE返回<null>,空字符串。

from

字符串表达式中的子字符串数,从1开始计算。 它必须是正整数、整型变量的名称或计算结果为正整数的表达式。 子字符串由分隔符分隔。

  • 如果from参数被省略或设置为1,$PIECE返回string-expression的第一个子字符串。 如果string-expression不包含指定的分隔符,from值为1将返回string-expression
  • 如果from参数通过计数来标识string-expression中的最后一个子字符串,则返回这个子字符串,无论它后面是否有分隔符。
  • 如果from的值是NULL,空字符串,零,或负数,并且指定了no to参数,$PIECE返回一个空字符串。 但是,如果指定了to参数,$PIECE将这些from值视为from=1
  • 如果from的值大于string-expression中子字符串的数量,$PIECE返回一个空字符串。

如果from参数与to参数一起使用,它将标识将作为字符串返回的子字符串范围的开始,并且应该小于to的值。

to

字符串表达式中结束from参数初始化的范围的子字符串的数目。 返回的字符串包括fromto子字符串,以及任何中间子字符串和分隔它们的分隔符。 to参数必须为正整数、整型变量的名称或计算结果为正整数的表达式。 to参数必须与from一起使用,并且应该大于from的值。

  • 如果from小于to$PIECE返回一个由该范围内所有分隔的子字符串组成的字符串,包括fromto子字符串。 这个返回的字符串包含此范围内的子字符串和分隔符。
  • 如果to大于带分隔符的子字符串的数量,则返回的字符串包含所有字符串数据(子字符串和分隔符),从from子字符串开始,一直到字符串表达式字符串的结尾。
  • 如果from等于to,则返回from子字符串。
  • 如果from大于to$PIECE返回一个空字符串。
  • 如果to是空字符串(null), $PIECE返回一个空字符串。

示例

下面的示例返回由","分隔符标识的第一个子字符串'Red':

SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black',',')

Red

下面的示例返回由","分隔符标识的第三个子字符串'Blue':

SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black',',',3)

Blue

下面的例子返回'Blue,Yellow,Orange'colorlist中的第三到第五个元素,用","分隔:

SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black',',',3,5)

Blue,Yellow,Orange

下面的$PIECE函数都返回'123',表明当from1时,双参数形式等价于三参数形式:

SELECT $PIECE('123#456#789','#') AS TwoArg

123
SELECT $PIECE('123#456#789','#',1) AS ThreeArg

123

下面的示例使用多字符分隔符字符串'#-#'返回第三个子字符串'789'。 这里,分隔符字符串的组成字符'#''-'可以用作数据值; 只保留指定的字符序列(#-#):

SELECT $PIECE('1#2-3#-#45##6#-#789','#-#',3)

3

下面的例子返回“MAR;APR;MAY”。 它们由第三个到第五个子字符串组成,由';'分隔符标识:

SELECT $PIECE('JAN;FEB;MAR;APR;MAY;JUN',';',3,5)

MAR;APR;MAY

下面的例子使用$PIECE从员工名和供应商联系人名中提取出姓氏,然后执行一个JOIN,返回与供应商联系人姓相同的员工的实例:

SELECT E.Name,V.Contact 
FROM Sample.Employee AS E INNER JOIN Sample.Vendor AS V 
ON $PIECE(E.Name,',')=$PIECE(V.Contact,',')

注意

使用$PIECE解压数据值

$PIECE 通常用于“解包”包含由分隔符分隔的多个字段的数据值。典型的分隔符包括斜杠 (/)、逗号 (,)、空格 () 和分号 (;)。以下示例值非常适合与 $PIECE 一起使用:

'John Jones/29 River St./Boston MA, 02095'
'Mumps;Measles;Chicken Pox;Diptheria'
'45.23,52.76,89.05,48.27'

$PIECE 和 $LENGTH

$LENGTH 的双参数形式根据分隔符返回字符串中子字符串的数量。使用 $LENGTH 确定字符串中子字符串的数量,然后使用 $PIECE 提取单个子字符串。

$PIECE and $LIST

$PIECE$LIST 函数使用的数据存储技术不兼容,不应组合使用。例如,尝试在使用 $LISTBUILD 创建的列表上使用 $PIECE 会产生不可预测的结果,应该避免。对于 SQL 函数和相应的 ObjectScript 函数都是如此。

$LIST 函数指定子字符串而不使用指定的分隔符。如果留出分隔符或字符序列不适合数据类型(例如,位串数据),则应使用 $LISTBUILD$LIST SQL 函数来存储和检索子字符串。

Null Values

$PIECE 不区分具有空字符串值 (NULL) 的分隔子字符串和不存在的子字符串。两者都返回 <null>,,即空字符串值。例如,以下示例均返回值为 7 的空字符串:

SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black',',',7)

NUll
SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black,',',',7)

NULL

在第一种情况下,没有第七个子串;返回一个空字符串。在第二种情况下,有第七个子字符串,由字符串表达式字符串末尾的分隔符指示;第七个子字符串的值是空字符串。

以下示例显示字符串表达式中的空值。它提取子字符串 3。此子字符串存在,但包含一个空字符串:

SELECT $PIECE('Red,Green,,Blue,Yellow,Orange,Black,',',',3)

NULL

以下示例还返回空字符串,因为指定的子字符串不存在:

SELECT $PIECE('Red,Green,,Blue,Yellow,Orange,Black,',',',0)

NULL
SELECT $PIECE('Red,Green,,Blue,Yellow,Orange,Black,',',',8,20)

NULL

在以下示例中,$PIECE 函数返回整个字符串表达式字符串,因为字符串表达式字符串中没有出现分隔符:

SELECT $PIECE('Red,Green,Blue,Yellow,Orange,Black,','#')

Red,Green,Blue,Yellow,Orange,Black,

嵌套 $PIECE 操作

要执行复杂的提取,可以将 $PIECE 引用相互嵌套。内部 $PIECE 返回一个由外部 $PIECE 操作的子字符串。每个 $PIECE 都使用自己的分隔符。例如,以下返回状态缩写“MA”

SELECT $PIECE($PIECE('John Jones/29 River St./Boston MA 02095','/',3),' ',2)

MA

下面是嵌套$PIECE操作的另一个例子,它使用了分隔符的层次结构。 首先,内部的$PIECE使用插入符号(^)分隔符来查找字符串的第二部分'A,B,C'。 然后外部$PIECE使用逗号()分隔符返回子串'A,B,C'的第一块和第二块('A,B'):

SELECT $PIECE($PIECE('1,2,3^A,B,C^@#!','^',2),',',1,2)

A,B
0
0 166
文章 姚 鑫 · 四月 8, 2022 1m read

第106章 SQL函数 PI

返回pi常数值的标量数值函数。

大纲

{fn PI()}
{fn PI}

描述

PI不接受参数。 它返回数学常数pi作为数据类型NUMERIC,精度为19,刻度为18

PI只能使用ODBC标量函数(花括号)语法调用。 请注意,参数括号是可选的。

描述

下面的例子都返回pi的值:

SELECT {fn PI()} AS ExactPi

3.141592653589793238
SELECT {fn PI} AS ExactPi

3.141592653589793238
0
0 96
文章 姚 鑫 · 四月 7, 2022 1m read

第105章 SQL函数 %OID

返回 ID 字段的 OID 的标量函数。

大纲

%OID(id_field)

参数

  • id_field - ID 字段或引用字段的字段名称。

描述

%OID 采用字段名称并返回对象的完整 OID(对象 ID)。该字段必须是 ID 字段或引用字段(外键字段)。在 id_field 中指定任何其他类型的字段会生成 SQLCODE -1 错误。

示例

以下示例显示了与引用字段一起使用的 %OID

SELECT Name, Spouse, %OID(Spouse)
FROM Sample.Person
WHERE Spouse IS NOT NULL

以下嵌入式 SQL 示例显示了与引用字段一起使用的 %OID

/// d ##class(PHA.TEST.SQLFunction).Oid()
ClassMethod Oid()
{
	&sql(SELECT Name, Spouse, %OID(Spouse)
			INTO :n,:s,:soid
		FROM Sample.Person)
	w !,"Name is:",n
	w !,"Spouse name is:",s
	w !,"Spouse OID is:",soid
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Oid()
 
Name is:yaoxin
Spouse name is:13
Spouse OID is:13Sample.Person
0
0 81
文章 姚 鑫 · 四月 6, 2022 2m read

第104章 SQL函数 %ODBCOUT

ODBC 格式返回表达式的格式转换函数。

大纲

%ODBCOUT(expression)

%ODBCOUT expression

参数

  • expression - 要转换的表达式。字段名称、包含字段名称的表达式或以可转换数据类型(例如 DATE%List)返回值的函数。不能是流字段。

描述

%ODBCOUT 在通过字段或数据类型的 LogicalToOdbc 方法传递值后以 ODBC 格式返回表达式。 ODBC 格式是可以通过 ODBC 呈现数据的格式。当数据暴露给 ODBC/SQL 时使用这种格式。可用的格式对应于 ODBC 定义的格式。

%ODBCOUT 通常用于 SELECT 列表选择项。它可以在 WHERE 子句中使用,但不鼓励这种使用,因为使用 %ODBCOUT 会阻止在指定字段上使用索引。

应用 %ODBCOUT 将列标题名称更改为诸如“Expression_1”之类的值;因此,通常需要指定列名别名,如下面的示例所示。

%ODBCOUT 是否转换日期取决于日期字段或函数返回的数据类型。 %ODBCOUT 转换 CURDATECURRENT_DATECURTIMECURRENT_TIME 值。它不转换 CURRENT_TIMESTAMPGETDATEGETUTCDATENOW$HOROLOG 值。

示例

以下示例显示了同一字段的默认显示格式、%ODBCIN%ODBCOUT 格式。

SELECT FavoriteColors,%ODBCIN(FavoriteColors) AS InVal,
%ODBCOUT(FavoriteColors) AS OutVal
FROM Sample.Person
0
0 91
文章 姚 鑫 · 四月 5, 2022 1m read

第103章 SQL函数 %ODBCIN

以逻辑格式返回表达式的格式转换函数。

大纲

%ODBCIN(expression)

%ODBCIN expression

参数

  • expression - 要转换的表达式。

描述

%ODBCIN 在通过字段或数据类型的 OdbcToLogical 方法传递值后以逻辑格式返回表达式。逻辑格式是数据的内存格式(执行操作的格式)。

%ODBCIN 是一个 SQL 扩展。

示例

以下示例显示了同一字段的默认显示格式、%ODBCIN%ODBCOUT 格式。

SELECT FavoriteColors,%ODBCIN(FavoriteColors) AS InVal,
%ODBCOUT(FavoriteColors) AS OutVal
FROM Sample.Person

image

以下示例在 WHERE 子句中使用 %ODBCIN

SELECT Name,DOB,%ODBCOUT(DOB) AS Birthdate
FROM Sample.Person
WHERE DOB BETWEEN %ODBCIN('2000-01-01') AND %ODBCIN('2018-01-01') 

image

0
0 86
文章 姚 鑫 · 四月 4, 2022 2m read

第102章 SQL函数 %OBJECT

标量函数,它打开一个流对象并返回相应的 oref

大纲

%OBJECT(stream)

参数

  • stream - 作为流字段名称的表达式。

描述

%OBJECT 用于打开一个流对象并返回流字段的 oref(对象引用)。

流字段上的 SELECT 返回流字段的完全形成的 oid(对象 ID)值。流字段上的 SELECT %OBJECT 返回流字段的 oref(对象引用)。这在以下示例中显示,其中 NotesPicture 都是流字段:

/// d ##class(PHA.TEST.SQLFunction).Object()
ClassMethod Object()
{
	s myquery = "SELECT TOP 3 Title,Notes,%OBJECT(Picture) AS Photo FROM Sample.Employee"
	s tStatement = ##class(%SQL.Statement).%New()
	s qStatus = tStatement.%Prepare(myquery)
	s rset = tStatement.%Execute()
	while rset.%Next() {
		w "String field: ",rset.Title,!
		w "Stream field oid: ",rset.Notes,!
		w "Stream field oref: ",rset.Photo,!!
	}
	w !,"End of data"
}

DHC-APP>d ##class(PHA.TEST.SQLFunction).Object()
String field: test
Stream field oid:
Stream field oref:
 
String field: Assistant Systems Engineer
Stream field oid:
Stream field oref:
 
String field: Systems Engineer
Stream field oid:
Stream field oref:
 
 
End of data

如果 stream 不是流字段,则 %OBJECT 生成 SQLCODE -128 错误。

%OBJECT 可用作以下函数的参数:

CHARACTER_LENGTH(%OBJECT(streamfield)), CHAR_LENGTH(%OBJECT(streamfield)), or DATALENGTH(%OBJECT(streamfield)).
SUBSTRING(%OBJECT(streamfield),start,length).

可以通过在流字段上发出 SELECT 来执行相同的操作,然后通过调用 $Stream.Object.%Open() 类方法打开流 oid,该方法从 oid 生成一个 oref

SET oref = ##class(%Stream.Object).%Open(oid)
0
0 123
文章 姚 鑫 · 四月 3, 2022 3m read

第101章 SQL函数 NVL

测试 NULL 并返回适当表达式的函数。

大纲

NVL(check-expression,replace-expression)

参数

  • check-expression - 要计算的表达式。
  • replace-expression - 如果 check-expressionNULL,则返回的表达式。

NVL 返回与检查表达式相同的数据类型。

描述

NVL 计算检查表达式并返回以下两个值之一:

  • 如果 check-expressionNULL,则返回 replace-expression
  • 如果 check-expression 不为 NULL,则返回 check-expression

参数 check-expressionreplace-expression 可以具有任何数据类型。如果它们的数据类型不同,SQL 会将 replace-expression 转换为 check-expression 的数据类型,然后再进行比较。返回值的数据类型始终与 check-expression 的数据类型相同,除非 check-expression 为字符数据,此时返回值的数据类型为 VARCHAR2。

请注意,NVL 支持 Oracle 兼容性,并且与 ISNULL 函数相同。

日期和时间显示转换

某些检查表达式数据类型需要从逻辑模式转换为 ODBC 模式或显示模式。例如 DATETIME 数据类型。如果replace-expression的值不是同一个数据类型,这个值不能在ODBC模式或Display模式下转换,会产生SQLCODE错误:-146 for DATE data type; -147 用于 TIME 数据类型。例如,ISNULL(DOB,'nodate')不能在 ODBC 模式或 Display 模式下执行;它发出%msg Error: 'nodate' is an invalid ODBC/JDBC Date value or Error: 'nodate' is an invalid DISPLAY Date value. 。要在 ODBC 模式或显示模式下执行此语句,必须将值转换为适当的数据类型ISNULL(DOB,CAST('nodate' as DATE))。这导致日期 0,显示为 1840-12-31

NULL 处理函数比较

下表显示了各种 SQL 比较函数。如果逻辑比较测试为 TrueAB 相同),则每个函数返回一个值,如果逻辑比较测试为 FalseAB 不同),则返回另一个值。这些函数允许执行 NULL 逻辑比较。不能在实际相等(或不相等)条件比较中指定 NULL

SQL FunctionComparisonTest Return Value
IFNULL(ex1,ex2) [two-argument form]ex1 = NULLTrue returns ex2 False returns NULL
IFNULL(ex1,ex2,ex3) [three-argument form]ex1 = NULLTrue returns ex2 False returns ex3
{fn IFNULL(ex1,ex2)}ex1 = NULLTrue returns ex2 False returns ex1
ISNULL(ex1,ex2)ex1 = NULLTrue returns ex2 False returns ex1
NVL(ex1,ex2)ex1 = NULLTrue returns ex2 False returns ex1
NULLIF(ex1,ex2)ex1 = ex2True returns NULL False returns ex1
COALESCE(ex1,ex2,...)ex = NULL for each argumentTrue tests next ex argument. If all ex arguments are True (NULL), returns NULL. False returns ex

示例

以下示例返回替换表达式 (99),因为检查表达式为 NULL

SELECT NVL(NULL,99) AS NullTest

99

以下示例返回检查表达式 (33),因为检查表达式不为 NULL

SELECT NVL(33,99) AS NullTest

33

如果 FavoriteColorsNULL,则以下动态 SQL 示例返回字符串“No Preference”;否则,它返回 FavoriteColors 的值:

/// d ##class(PHA.TEST.SQLFunction).Nvl()
ClassMethod Nvl()
{
	s myquery = 3
	s myquery(1) = "SELECT Name,"
	s myquery(2) = "NVL(FavoriteColors,'No Preference') AS ColorChoice "
	s myquery(3) = "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.SQLFunction).Nvl()
Name    ColorChoice
yaoxin  $lb("Red","Orange","Yellow")
xiaoli  No Preference
姚鑫    No Preference
姚鑫    No Preference
姚鑫    No Preference
姚鑫    $lb("Red","Orange","Yellow","Green")
姚鑫    $lb("Red","Orange","Yellow","Green","Green")
0
0 115
文章 姚 鑫 · 四月 2, 2022 2m read

第100章 SQL函数 NULLIF

如果两个表达式具有相同的值,则返回 NULL 的函数。

大纲

NULLIF(expression1,expression2)

参数

  • expression1 - 表达式,可以是列名、数字或字符串文字、主变量或另一个标量函数的结果。
  • expression2 - 表达式,可以是列名、数字或字符串文字、主变量或另一个标量函数的结果。

NULLIF 返回与 expression1 相同的数据类型。

描述

如果 expression1 的值等于 expression2 的值,则 NULLIF 函数返回 NULL。否则,它返回 expression1 值。

NULLIF 等价于:

SELECT CASE 
WHEN value1 = value2 THEN NULL
ELSE value1
END
FROM MyTable

NULL 处理函数比较

下表显示了各种 SQL 比较函数。如果逻辑比较测试为 TrueAB 相同),则每个函数返回一个值,如果逻辑比较测试为 FalseAB 不同),则返回另一个值。这些函数允许执行 NULL 逻辑比较。不能在实际相等(或不相等)条件比较中指定 NULL

SQL FunctionComparisonTest Return Value
IFNULL(ex1,ex2) [two-argument form]ex1 = NULLTrue returns ex2 False returns NULL
IFNULL(ex1,ex2,ex3) [three-argument form]ex1 = NULLTrue returns ex2 False returns ex3
{fn IFNULL(ex1,ex2)}ex1 = NULLTrue returns ex2 False returns ex1
ISNULL(ex1,ex2)ex1 = NULLTrue returns ex2 False returns ex1
NVL(ex1,ex2)ex1 = NULLTrue returns ex2 False returns ex1
NULLIF(ex1,ex2)ex1 = ex2True returns NULL False returns ex1
COALESCE(ex1,ex2,...)ex = NULL for each argumentTrue tests next ex argument. If all ex arguments are True (NULL), returns NULL. False returns ex

示例

以下示例使用 NULLIF 函数将 Age=20 的所有记录的显示字段设置为空:

SELECT Name,Age,NULLIF(Age,20) AS Nulled20
FROM Sample.Person
0
0 86
文章 姚 鑫 · 四月 1, 2022 4m read

第九十九章 SQL函数 NOW

返回当前本地日期和时间的日期/时间函数。

大纲

NOW()

{fn NOW}
{fn NOW()}

描述

NOW 不接受任何参数。参数括号对于 ODBC 标量语法是可选的;它们对于 SQL 标准函数语法是必需的。

NOW 以时间戳的形式返回该时区的当前本地日期和时间;它会根据本地时间变体进行调整,例如夏令时。

NOW 可以返回 %TimeStamp 数据类型格式 (yyyy-mm-dd hh:mm:ss.ffff) 或 %PosixTime 数据类型格式(编码的 64 位有符号整数)的时间戳。以下规则确定返回的时间戳格式:

  1. 如果当前时间戳提供给数据类型为 %PosixTime 的字段,则当前时间戳值以 POSIXTIME 数据类型格式返回。例如,WHERE PosixField=NOW()INSERT INTO MyTable (PosixField) VALUES (NOW())
  2. 如果当前时间戳提供给数据类型为 %TimeStamp 的字段,则当前时间戳值以 TIMESTAMP 数据类型格式 (yyyy-mm-dd hh:mm:ss) 返回。它的 ODBC 类型是 TIMESTAMPLENGTH16PRECISION19。小时以 24 小时格式表示。所有字段都保留前导零。例如,WHERE TSField=NOW()INSERT INTO MyTable (TSField) VALUES (NOW())
  3. 如果在没有上下文的情况下提供当前时间戳,则以 TIMESTAMP 数据类型格式返回当前时间戳值。例如SELECT NOW()

要更改默认日期时间字符串格式,请使用带有各种日期和时间选项的 SET OPTION 命令。

可以使用 CASTCONVERT 函数更改时间戳、日期和时间的数据类型。

精度的小数秒

默认情况下,NOW 不返回小数秒的精度。它不支持精确参数。但是,通过更改系统范围的默认时间精度,可以使系统范围内的所有 NOW 函数返回此配置的小数秒精度位数。系统范围默认时间精度的初始配置设置为 0(无小数秒);最高设置为 9。

GETDATE 在功能上与 NOW 相同,只是 GETDATE 提供了一个精度参数,允许覆盖系统范围的默认时间精度;如果省略精度参数,则 GETDATE 采用配置的系统范围的默认时间精度。

CURRENT_TIMESTAMP 有两种语法形式: 没有参数括号,CURRENT_TIMESTAMP 在功能上与 NOW 相同。带参数括号的 CURRENT_TIMESTAMP(precision) 在功能上与 GETDATE 相同,只是 CURRENT_TIMESTAMP() 精度参数是强制性的。 CURRENT_TIMESTAMP() 始终返回其指定的精度并忽略配置的系统范围默认时间精度。

小数秒总是被截断而不是四舍五入到指定的精度。

SYSDATE 在功能上与无参数的 CURRENT_TIMESTAMP 函数相同。

其他当前时间和日期功能

NOWGETDATECURRENT_TIMESTAMPSYSDATE 都根据本地时区设置返回当前本地日期和时间。

GETUTCDATE 以时间戳的形式返回当前的通用时间常数 (UTC) 日期和时间。由于 UTC 时间不依赖于本地时区,并且不受本地时间变量(例如夏令时)的影响,因此该功能对于在不同时区的用户访问同一数据库时应用一致的时间戳很有用。 GETUTCDATE 支持小数秒精度。当前的 UTC 时间戳也由 ObjectScript $ZTIMESTAMP 特殊变量提供。

要仅返回当前日期,请使用 CURDATECURRENT_DATE。要仅返回当前时间,请使用 CURRENT_TIMECURTIME。这些函数使用 DATETIME 数据类型。 TIMEDATE 数据类型将它们的值存储为 $HOROLOG 格式的整数。这些函数都不支持精度。

示例

下面的例子显示了这三种语法形式是等价的; all 返回当前的本地日期和时间作为时间戳:

SELECT NOW(),{fn NOW},{fn NOW()}

2022/3/16 10:08:51	2022/3/16 10:08:51	2022/3/16 10:08:51

以下嵌入式 SQL 示例比较了本地(特定于时区)和通用(独立于时区)时间戳:

/// d ##class(PHA.TEST.SQLFunction).Now()
ClassMethod Now()
{
	&sql(
		SELECT NOW(),GETUTCDATE() INTO :a,:b
	)
	if SQLCODE '= 0 {
		w !,"Error code ",SQLCODE 
	} else {
		w !,"Local timestamp is:  ",a
		w !,"UTC timestamp is:    ",b
		w !,"$ZTIMESTAMP is:      ",$ZDATETIME($ZTIMESTAMP,3,,3)
	}
}
DHC-APP>d ##class(PHA.TEST.SQLFunction).Now()
 
Local timestamp is:  2022-03-16 10:09:42
UTC timestamp is:    2022-03-16 02:09:42
$ZTIMESTAMP is:      2022-03-16 02:09:42.584

以下示例将 Orders 表的选定行中的 LastUpdate 字段设置为当前系统日期和时间:

UPDATE Orders SET LastUpdate = {fn NOW()}
  WHERE Orders.OrderNumber=:ord
0
0 100