文章 姚 鑫 · 六月 30, 2022 2m read

第十四章 信号(四)- 多进程任务示例

可根据此思想进行多任务启动查询汇总数据。

原理

  • 利用job机制开启后台进程。
  • 利用loop循环减少进程的数量等于开启进程的数量,判断多进程任务是否完成。
  1. 创建表并插入1000W条数据,统计Moeny字段总金额

  2. 创建demo代码如下。

Class Demo.SemaphoreDemo Extends %RegisteredObject
{

///  Do ##class(Demo.SemaphoreDemo).Sample(5)
ClassMethod Sample(pJobCount = 3)
{
	k ^yx("Amt"),^yxAmt
	
	 /* 1.启动信号 */
    s mSem = ##class(Demo.Sem).%New()
    If ('($isobject(mSem))) 
    {
		q "启动失败"
    }
    
    /* 2. 初始化信号量为0 */
    d mSem.Init(0)
    
    s t1 = $zh
    
    /* 3. 按指定数量,启动后台任务 */
    for i = 1 : 1 : pJobCount
    {
        j ..Task(i)
    }
    
    w "启动job时间:"_ ($zh - t1),!
	
    /* 4. 等待后台任务完成 */
    s tCount = i,tSC = 0
    /* 后台任务完成的判断条件是:减少的信号量=总后台任务数 */
    while (tSC < tCount)
    {
        s tSC = tSC + mSem.Decrement(tCount, 10)
    }
    
    w "完成时间:"_ ($zh - t1),!
    
    
	s moneyAmt = 0

		
	s data = ""
	for {
		s data = $o(^yxAmt(data))
		q:(data = "")
		s moneyAmt = moneyAmt + ^yxAmt(data)
	}
	d mSem.Delete()
    w "总金额" _ moneyAmt,!
    
    w "汇总时间:"_ ($zh - t1),!
	q
}

ClassMethod Task(i)
{
    s tSem = ##class(Demo.Sem).%New()
	s moneyAmt = 0
	for j = (i * 100000) + 1 : 1 : (i + 1) * 100000 {
		s money = $li(^M.YxPersonD(j), 3)
		s moneyAmt = moneyAmt + money
	}
	s ^yxAmt("moneyAmt" _ i) = moneyAmt
	s ^yx("Amt") = $i(^yx("Amt"))
    d tSem.Open(##class(Demo.Sem).Name())
    d tSem.Increment(1)
    d tSem.%Close()
	q moneyAmt
}
}
0
0 128
文章 姚 鑫 · 六月 29, 2022 10m read

第十三章 信号(三)- 示例演示

运行示例

MainProducerConsumer 这三个类中的每一个都有自己的 方法,最好在各自的终端窗口中运行它们。每次运行时,它都会显示它为日志生成的消息。一旦用户通过提供它正在等待的输入来响应 类, 的 方法将终止删除信号量。然后,用户可以通过键入命令查看所有进程的合并日志文件的显示

  Do ##class(Semaphore.Util).ShowLog()

注意:以下所有示例都假定所有类都已在命名空间中编译。

示例 1 - 创建和删除信号量

最简单的例子演示了信号量的创建和销毁。它使用 类。请执行下列操作:

  1. 打开一个终端窗口。
  2. 输入命令——
Do ##class(Semaphore.Main).Run()
  1. 该方法创建信号量。如果成功,将看到消息“输入任何字符以终止运行方法”。按下 Enter 键。该方法显示信号量的初始化值,将其删除,然后退出。
  2. 通过发出命令显示日志文件

按照上述步骤在终端窗口中显示的消息示例如下

示例 2——创建信号量并连续递增它

这个例子展示了生产者在工作,以及从两个进程中捕获日志消息。

  1. 打开两个单独的终端窗口。称它们为“A”“B”
  2. 在窗口 A 中,键入以下命令,但不要在末尾键入 ENTER 键 -
Do ##class(Semaphore.Main).Run()
0
0 169
文章 姚 鑫 · 六月 27, 2022 7m read

第十二章 信号(二)- 生产者消费者示例

下面是一系列使用信号量实现生产者/消费者场景的类。 “主”进程初始化信号量并等待用户指示活动已全部完成。生产者在循环中随机增加一个信号量值,更新之间的延迟可变。消费者尝试在随机时间从信号量中删除随机数量,也是在循环中。该示例由 5 个类组成:

  • Main – 初始化环境并等待信号量上的活动完成的类。
  • Counter – 实现信号量本身的类。它记录它的创建以及由于信号量在等待列表中而发生的任何回调。
  • Producer – 一个类,其主要方法增加信号量值。增量是一个随机选择的小整数。完成增量后,该方法会在下一个增量之前延迟一小段随机数秒。
  • Consumer 消费者——这是对生产者的补充。此类的主要方法尝试将信号量减少一个随机选择的小整数。它将递减请求添加到其等待列表中,等待时间也是随机选择的秒数。
  • Util - 这个类有几个方法被示例的其他类使用。几种方法解决了为所有活动维护公共日志的问题;其他人解决了多个消费者和多个生产者的命名问题。

注意:组成这些类的代码特意写得简单。尽可能地,每个语句只完成一个动作。这应该使用户更容易和更直接地修改示例。

Class: Semaphore.Main

此类建立演示环境。它调用实用程序类来初始化日志和名称索引工具。

0
0 173
文章 姚 鑫 · 六月 26, 2022 7m read

第十一章 信号(一) - 概念

背景

维基百科对信号量有这样的定义:“在计算机科学中,特别是在操作系统中,信号量是一种变量或抽象数据类型,用于控制多个进程在并行编程或多用户环境中对公共资源的访问。”信号量不同于互斥体(或锁)。互斥锁最常用于管理竞争进程对单个资源的访问。当一个资源有多个相同的副本并且这些副本中的每一个都可以由单独的进程同时使用时,就会使用信号量。

考虑一个办公用品商店。它可能有几台复印机供其客户使用,但每台复印机一次只能由一个客户使用。为了控制这一点,有一组键可以启用机器并记录使用情况。当客户想要复印文件时,他们向职员索取钥匙,使用机器,然后归还钥匙,并支付使用费。如果所有机器都在使用,客户必须等到钥匙归还。保存键的位置用作信号量。

该示例可以进一步推广到包括不同类型的复印机,也许可以通过它们可以制作的副本的大小来区分。在这种情况下,将有多个信号量,如果复制者在复制的大小上有任何重叠,那么希望复制共同大小的客户将有两个资源可供提取。

介绍

信号量是共享对象,用于在进程之间提供快速、高效的通信。每个信号量都是类 %SYSTEM.Semaphore 的一个实例。信号量可以建模为一个共享变量,它包含一个 64 位非负整数。信号量上的操作在共享它的所有进程中以同步的方式更改变量的值。按照惯例,值的变化会在共享信号量的进程之间传递信息。

0
0 219
文章 姚 鑫 · 六月 25, 2022 2m read

第十章 设置结构化日志记录(二)

注:IRIS有,Cache无。

启用结构化日志记录

^LOGDMN 例程允许管理结构化日志记录;还有一个基于类的 API,将在下一节中介绍。

要使用 ^LOGDMN 启用结构化日志记录:

  1. 打开终端并输入以下命令:
set $namespace="%sys"
do ^LOGDMN

这将启动一个带有以下提示的例程:

 
1) Enable logging
2) Disable logging
3) Display configuration
4) Edit configuration
5) Set default configuration
6) Display logging status
7) Start logging
8) Stop logging
9) Restart logging
 
LOGDMN option?
  1. 4 以便可以指定配置详细信息。然后,该例程会提示输入以下项目:

a. 最低日志级别,以下之一:

  • -2 — 详细的调试消息(例如十六进制转储)。
  • -1 — 不太详细的调试消息。
  • — 信息性消息,包括所有审计事件。
  • 1(默认值)— 警告,表示可能需要注意但未中断操作的问题。
  • 2 — 严重错误,表明问题已中断操作。
  • — 致命错误,表示问题导致系统无法运行。

b. 管道命令,它指定系统将结构化日志发送到哪里。

0
0 170
文章 姚 鑫 · 六月 24, 2022 4m read

第九章 设置结构化日志记录(一)

IRIS 支持结构化日志记录。

创建多个日志,每个日志用于不同的目的。从以前的产品迁移过来的客户可以像过去一样利用这些日志,但现在还可以将所有日志信息导入一个单一的、中央的、机器可读的日志文件——结构化日志。然后可以将此文件与第三方分析工具一起使用。

本文概述了结构化日志中的信息,展示了日志示例,并描述了如何启用结构化日志记录。

结构化日志中可用的信息

当启用结构化日志记录时,系统会将相同的数据写入结构化日志,它也会写入其他日志(无论哪个)。例如,系统将相同的行写入messages.log 和结构化日志。

启用结构化日志记录后,结构化日志包含以下所有信息:

  • 写入messages.log 的信息。这包括需要注意的警报、有关系统启动和关闭的信息、有关日志文件和 WIJ 文件的高级信息、有关配置更改 (CPF) 的信息以及与许可相关的信息。
  • 写入审计数据库的信息。详细信息取决于正在审核的事件。

示例输出

本部分显示结构化日志记录实用程序的示例输出,用于名称/值对格式和 JSON 格式。

名称/值对

以下输出使用格式选项 (名称/值对)。此示例经过编辑以用于显示目的;在实际输出中,每个条目只占一行,条目之间没有空行。

when="2019-08-01 18:43:02.216" pid=8240 level=SEVERE event=Utility.Event 
text="Previous system shutdown was abnormal, system forced down or crashed"

when="2019-08-01 18:43:05.290" pid=8240 level=SEVERE event=Utility.Event 
text="LMF Error: No valid license key. Local key file not found and LicenseID not defined."

when="2019-08-01 18:43:05.493" pid=8240 level=WARNING event=Generic.Event 
text="Warning: Alternate and primary journal directories are the same"

when="2019-08-01 18:46:10.493" pid=11948 level=WARNING event=System.Monitor 
text="CPUusage Warning: CPUusage = 79 ( Warnvalue is 75)."
0
0 209
文章 姚 鑫 · 六月 23, 2022 3m read

第八章 操作位和位串(四)

操作以整数形式实现的位串

设置位

要创建一个存储为整数的新位串,请对每个位求和 2 的幂:

set bitint = (2**2) + (2**5) + (2**10)
 
write bitint
1060

要将现有位串中的位设置为 1,请使用 $zboolean 函数(逻辑 OR)的选项7

set bitint = $zboolean(bitint, 2**4, 7)

write bitint
1076

要将现有位串中的位设置为 ,请使用 函数的选项 :


set bitint = $zboolean(bitint, 2**4, 2)

write bitint
1060

要在现有位串中切换位,请使用 函数(逻辑 )的选项 :

测试位是否已设置

要将位字符串显示为整数,可以使用如下方法,该方法循环位并使用 函数:

查找设置位

此方法使用函数将位字符串中的哪些位设置为整数,该函数返回以10为底的对数值。该方法删除越来越小的位串块,直到没有剩余:

执行按位算术

使用 函数对存储为整数的位串执行按位逻辑运算。

对于此示例,假设有两个位串 和 ,存储为整数,以及一个 方法,如 中定义的,用于显示这些位。

使用 函数的选项 对位执行逻辑 :

使用 函数的选项 对位执行逻辑与:

转换为常规位串

0
0 166
文章 姚 鑫 · 六月 22, 2022 4m read

第七章 操作位和位串(三)

操作位串

要创建新的位串,请使用 $bit 函数将所需位设置为 1

kill bitstring
 
set $bit(bitstring, 3) = 1
 
set $bit(bitstring, 6) = 1
 
set $bit(bitstring, 11) = 1

使用 将现有位串中的位设置为 1

set $bit(bitstring, 5) = 1

使用 将现有位串中的位设置为 0

set $bit(bitstring, 5) = 0

由于位串中的第一位是位 ,因此尝试设置位 会返回错误:

测试位是否已设置

要测试是否在现有位串中设置了位,还可以使用 函数:

如果测试未明确设置的位,则 $bit 返回 0:

显示位

要显示位串中的位,请使用 $bitcount 函数获取位串中位的计数,然后遍历位:

还可以使用 来计算位串中 或 的数量:

查找设置位

要查找在位串中设置了哪些位,请使用 函数,该函数返回指定值的下一位的位置,从位串中的给定位置开始:

此方法搜索字符串并在 返回 时退出,表示没有找到更多匹配项。

在测试位串的比较时要非常小心。

例如,可以有两个位串 和 ,它们具有相同的位集:

然而,如果你比较它们,你会发现它们实际上并不相等:

如果你使用 ,你可以看到这两个比特环的内部表示是不同的:

在这种情况下, 将第 位设置为 :

0
0 143
文章 姚 鑫 · 六月 21, 2022 3m read

第六章 操作位和位串(二)

将位序列存储为整数

如果要将一系列布尔参数传递给方法,一种常见的方法是将它们作为编码为单个整数的位序列传递。

例如,Security.System.ExportAll() 方法用于从 IRIS 实例中导出安全设置。如果查看此方法的类引用,将看到它的定义如下:

classmethod ExportAll(FileName As %String = "SecurityExport.xml", 
ByRef NumExported As %String, Flags As %Integer = -1) as %Status

第三个参数 Flags 是一个整数,其中每个位代表一种可以导出的安全记录。

0
0 162
文章 姚 鑫 · 六月 20, 2022 4m read

第五章 操作位和位串

有时可能希望在基于数据平台的应用程序中存储一系列相关的布尔值。可以创建许多布尔变量,也可以将它们存储在数组或列表中。或者可以使用称为“位串”的概念,它可以定义为位序列,首先呈现最低有效位。位串允许您以非常有效的方式存储此类数据,无论是在存储空间还是处理速度方面。

位串可以以两种方式之一存储,作为压缩字符串或整数。如果在没有上下文的情况下听到术语“位串”,则表示位序列存储为压缩字符串。本文向介绍了这两种类型的位串,然后介绍了一些可用于操作它们的技术。

将位序列存储为位串

存储位序列的最常见方式是在位串中,这是一种特殊的压缩字符串。除了节省存储空间外,还可以使用 ObjectScript 系统函数有效地操作位串。

这样的系统函数是 $factor,它将整数转换为位串。我们可以通过执行以下语句将整数 11744 转换为位串:

set bitstring = $factor(11744)

要查看位串内容的表示,可以使用 命令:

zwrite bitstring
bitstring=$zwc(128,4)_$c(224,45,0,0)/*$bit(6..9,11,12,14)*/

起初它看起来很神秘,但在输出的末尾,会看到一条注释,其中显示了已设置的实际位的列表:67、、、、 和 。位串中的位 表示 ,位 表示 ,依此类推。将所有位加在一起,我们得到 。

0
0 187
文章 姚 鑫 · 六月 19, 2022 3m read

第四章 锁定和并发控制(四)

避免死锁

增量锁定具有潜在危险,因为它可能导致称为死锁的情况。当两个进程各自对已被另一个进程锁定的变量断言增量锁定时,就会出现这种情况。因为尝试的锁是增量的,所以现有的锁不会被释放。结果,每个进程在等待另一个进程释放现有锁的同时挂起。

举个例子:

  1. 进程 A 发出此命令:lock + ^MyGlobal(15)
  2. 进程 B 发出此命令:
  3. 进程 A 发出此命令:

LOCK 命令不返回;进程被阻塞,直到进程 释放这个锁。

  1. 进程 B 发出此命令:lock + ^MyGlobal(15)

LOCK 命令不返回;进程被阻塞,直到进程 释放这个锁。但是,进程 A 被阻塞,无法释放锁。现在这些进程都在等待对方。

有几种方法可以防止死锁:

  • 始终包含 timeout 参数。
  • 对于发出增量 命令的顺序,请遵循严格的协议。只要所有进程都遵循相同的锁名称顺序,就不会发生死锁。一个简单的协议是按排序顺序添加锁。
  • 使用简单锁定而不是增量锁定;也就是说,不要使用 运算符。如前所述,对于简单锁定, 命令首先释放进程持有的所有先前锁定。 (然而,在实践中,简单的锁定并不经常使用。)

如果发生死锁,可以使用管理门户或

锁的实际用途

本节介绍在实践中使用锁的基本方法。

控制对应用程序数据的访问

0
0 227
文章 姚 鑫 · 六月 17, 2022 7m read

第三章 锁定和并发控制(三)

升级锁

使用升级锁来管理大量锁。当锁定数组的节点时,它们是相关的,特别是当将多个节点锁定在同一下标级别时。

当给定进程在同一数组中的给定下标级别创建了超过特定数量(默认为 1000)的升级锁时, 将删除所有单独的锁名称并用新锁替换它们。新锁位于父级,这意味着数组的整个分支被隐式锁定。示例(如下所示)演示了这一点。

应用程序应在合适的情况下尽快释放特定子节点的锁(与非升级锁完全相同)。当释放锁时, 会减少相应的锁计数。当的应用程序移除足够多的锁时,会移除父节点上的锁。第二小节显示了一个示例。

锁升级示例

假设有 1000^MyGlobal("sales","EU",salesdate) 形式的锁,其中 salesdate 表示日期。锁表可能如下所示:

image

注意 Owner 19776 的条目(这是拥有锁的进程)。 ModeCount 列指示这些是共享的、升级的锁。

当同一进程试图创建另一个相同形式的锁时, 会升级它们。它会移除这些锁并用名称为 ^MyGlobal("sales","EU") 的单个锁替换它们。现在锁表可能如下所示:

列表明这是一个共享的升级锁,它的计数是 1001

请注意以下关键点:

  • ^MyGlobal("sales","EU") 的所有子节点现在都被隐式锁定,遵循数组锁定的基本规则。
0
0 169
文章 姚 鑫 · 六月 16, 2022 4m read

第二章 锁定和并发控制(二)

关于零超时的说明

如上所述,如果您将 timeout 指定为 0, 会添加锁。但是,如果使用零超时锁定父节点,并且已经在子节点上锁定,则忽略零超时并使用内部 1 秒超时。

删除锁

要删除默认类型的锁,请使用 命令,如下所示:

LOCK -lockname

如果执行此命令的进程拥有具有给定名称的锁(默认类型),则此命令将删除该锁。或者,如果进程拥有多个锁(默认类型),此命令将删除其中一个。

或者删除另一种类型的锁:

LOCK -lockname#locktype

其中 是一串锁类型代码。

LOCK 命令的其他基本变体

为了完整起见,本节讨论 LOCK 命令的其他基本变体:使用它来创建简单的锁并使用它来删除所有锁。这些变化在实践中并不常见。

创建简单的锁

对于 命令,如果省略 + 运算符, 命令首先会删除该进程持有的所有现有锁,然后尝试添加新锁。在这种情况下,锁称为简单锁而不是增量锁。一个进程可以拥有多个简单的锁,如果该进程使用如下语法同时创建它们:

 LOCK (^MyVar1,^MyVar2,^MyVar3)

简单的锁在实践中并不常见,因为通常需要持有多个锁并在代码的不同步骤中获取它们。因此使用增量锁更实用。

但是,如果简单锁适合,请注意,可以在创建简单锁时指定 和 参数。此外,要删除一个简单的锁,可以使用带有减号 () 的 LOCK 命令。

0
0 93
文章 姚 鑫 · 六月 15, 2022 5m read

第一章 锁定和并发控制(一)

任何多进程系统的一个重要特征是并发控制,即防止不同进程同时更改特定数据元素的能力,从而导致损坏。 提供了一个锁管理系统。本文提供了一个概述。

此外,%Persistent 类提供了一种控制对象并发访问的方法,即 %OpenId() 的并发参数和该类的其他方法。这些方法最终使用本文讨论的 ObjectScript LOCK 命令。所有持久对象都继承这些方法。同样,系统会自动对 、 和 操作执行锁定(除非指定 关键字)。

类还提供方法 、%ReleaseLock()、、、 和 。

介绍

基本的锁定机制是 命令。此命令的目的是延迟一个进程中的活动,直到另一个进程发出可以继续进行的信号。

锁本身并不能阻止活动行为。锁定仅按约定起作用:它要求相互竞争的进程都使用相同的锁定名称实现锁定。例如,下面描述了一个常见的场景:

  1. 进程 A 发出 LOCK 命令, 创建一个锁(默认情况下,一个独占锁)。通常,进程 然后对中的节点进行更改。详细信息是特定于应用程序的。
  2. 进程 发出具有相同锁名称的 命令。因为存在一个现有的排他锁,所以进程 B 暂停。具体来说, 命令不返回,并且不能执行连续的代码行。
  3. 当进程释放锁时,进程中的命令最终返回,进程B继续。通常,进程 然后对同一中的节点进行更改。

锁名称

命令的参数之一是锁名称。

0
0 155
文章 姚 鑫 · 六月 14, 2022 5m read

第九章 其他参考资料(二)

特殊变量 (SQL)

系统提供的变量。

$HOROLOG
$JOB
$NAMESPACE
$TLEVEL
$USERNAME
$ZHOROLOG
$ZJOB
$ZPI
$ZTIMESTAMP
$ZTIMEZONE
$ZVERSION

SQL直接支持许多对象脚本特殊变量。这些变量包含系统提供的值。只要可以在SQL中指定文字值,就可以使用它们。

SQL特殊变量名不区分大小写。大多数可以使用缩写来指定。

0
0 153
文章 姚 鑫 · 六月 13, 2022 5m read

第八章 其他参考资料(一)

默认用户名和密码(SQL)

IRIS® 数据平台提供了用于登录数据库和开始使用的默认用户名和密码。默认用户名为“_SYSTEM”(大写),密码为“sys”。

SQLCODE错误代码(SQL)

执行大多数 SQL操作都会发出SQLCODE值。发出的值为0、和负整数值。

  • SQLCODE=0表示SQL操作成功完成。对于SELECT语句,这通常意味着从表中成功检索数据。但是,如果SELECT执行聚合操作(例如:),则聚合操作成功,即使中没有数据,也会发出;在这种情况下,返回,。
  • 表示SQL操作成功,但没有找到可操作的数据。发生这种情况的原因有很多。对于,这些包括:指定表不包含数据;表不包含满足查询条件的数据;或者行检索已到达表的最后一行。对于或,它们包括:指定的表不包含数据;或者表不包含满足子句条件的数据行。在这些情况下,。
  • 表示错误。负整数值指定发生的错误类型。是通用的致命错误代码。

字段约束(SQL)

字段约束指定管理字段允许的数据值的规则。一个字段可能有以下约束:

  • 非空:必须在每条记录中为该字段指定值(可接受空字符串)。
  • 唯一:如果在记录中为该字段指定值,则该值必须是唯一值(可接受的空字符串)。但是,可以为该字段创建多个没有值(NULL)的记录。
  • DEFAULT
0
0 286
文章 姚 鑫 · 六月 12, 2022 5m read

第七章 日期和时间构造

验证和转换 ODBC 日期、时间或时间戳。

大纲

{d 'yyyy-mm-dd'}
{d nnnnnn}

{t 'hh:mm:ss[.fff]'}
{t nnnnn.nnn}

{ts 'yyyy-mm-dd [hh:mm:ss.fff]'}
{ts 'mm/dd/yyyy [hh:mm:ss.fff]'}
{ts nnnnnn}

描述

这些构造采用 ODBC 日期、时间或时间戳格式的整数或字符串,并将其转换为相应的 IRIS 日期、时间或时间戳格式。他们执行数据输入以及值和范围检查。

{d 'string'}

{d 'string'}日期构造验证 ODBC 格式的日期。如果日期有效,它将以 IRIS 日期格式存储(逻辑模式)作为 的整数计数值。 IRIS 不附加默认时间值。要支持早于 的日期,必须在表中定义数据类型为 的日期字段,其中 是从 倒数的负天数(第 0 天)最大为 。

  • 小于 -672045 (0001-01-01) 或大于 2980013 (9999-12-31) 的整数会生成 错误。
  • 无效日期(例如非 ODBC 格式的日期或非闰年的日期 02-29): IRIS 生成 错误:是无效的 ODBC/JDBC 日期值”。
  • ODBC 时间戳值: IRIS 验证时间戳的日期和时间部分。
0
0 347
文章 姚 鑫 · 六月 11, 2022 4m read

第六章 数据类型(五)

数据类型的整数代码

在查询元数据和其他上下文中,为列定义的数据类型可以作为整数代码返回。 CType(客户端数据类型)整数代码列在 %SQL.StatementColumn clientType 属性中。

ODBC 和 JDBC 使用 xDBC 数据类型代码 (SQLType)。 ODBC 数据类型代码由 方法返回,如上例所示。 SQL Shell 元数据还返回 ODBC 数据类型代码。 JDBC 代码与 ODBC 代码相同,除了时间和日期数据类型的表示。下面列出了这些 ODBC 和 JDBC 值:

ODBC JDBC
0
0 170
文章 姚 鑫 · 六月 10, 2022 8m read

第五章 数据类型(四)

Strings

%Library.String 数据类型支持的最大字符串长度为 3,641,144 个字符。通常,极长的字符串应分配为 %Stream.GlobalCharacter 数据类型之一。

因为 IRIS 支持 xDBC 协议 50 和更高版本,所以没有强制执行 ODBC 或 JDBC 字符串长度限制。如果 IRIS 实例和 ODBC 驱动程序支持不同的协议,则使用两个协议中较低的一个。实际使用的协议记录在 ODBC 日志中。

请注意,默认情况下 IRIS 建立系统范围的 ODBC 最大长度为 ;此 ODBC 最大长度是可配置的。

列表结构

IRIS 支持列表结构数据类型 %List(数据类型类 )。这是一种压缩的二进制格式,不会映射到 SQL 的相应本机数据类型。在其内部表示中,它对应于数据类型 ,默认 为 。 IRIS 支持列表结构数据类型 (数据类型类 )对应于数据类型 ,默认 为 。

因此,动态 SQL 不能在 子句比较中使用 数据。也不能使用 INSERT 或 来设置 类型的属性值。

动态 SQL 将列表结构化数据的数据类型返回为 。要确定查询中的字段是数据类型 还是 ,可以使用 布尔标志。这些数据类型的 (客户端数据类型)整数代码是 。

如果使用 ODBC 或 JDBC 客户端,则使用 转换将 数据投影到 VARCHAR

0
0 274
文章 姚 鑫 · 六月 9, 2022 6m read

第四章 数据类型(三)

日期、时间、PosixTime 和时间戳数据类型

可以定义日期、时间和时间戳数据类型,并通过标准 SQL 日期和时间函数相互转换日期和时间戳。例如,可以使用 CURRENT_DATECURRENT_TIMESTAMP 作为使用该数据类型定义的字段的输入,或者使用 DATEADD、、 或 来操作使用该数据类型存储的日期值。

数据类型类 、、%Library.PosixTime、 和 对于 的处理方式如下:

  1. %Library.Date 类以及逻辑值为 +$HOROLOG$HOROLOG 的日期部分)的任何用户定义数据类型类都应使用 作为 。默认情况下, 和对应的 数据类型只接受正整数, 代表 。要支持早于 的日期,必须在表中定义数据类型为 的日期字段,其中 是从 倒数的负天数最大为。 可以将日期值存储为 到 范围内的无符号或负整数。日期值可以按如下方式输入:
  • 逻辑模式接受 整数值,例如 (2020 年 8 月 28 日)。
  • 显示模式使用 转换方法。它接受当前语言环境的显示格式的日期,例如。它还接受逻辑日期值(+HOROLOG 整数值)。
  • ODBC 模式使用 转换方法。它接受 ODBC 标准格式的日期,例如。它还接受逻辑日期值(+HOROLOG 整数值)。
  1. %Library.Time
0
0 250
文章 姚 鑫 · 六月 8, 2022 4m read

第三章 数据类型(二)

SQL 系统数据类型映射

上表中为 DDL 和 IRIS 数据类型表达式显示的语法是为 SQL.SystemDataTypes 配置的默认映射。对于提供的系统数据类型和用户数据类型,有单独的映射表可用。

要查看和修改当前数据类型映射,请转到管理门户,选择系统管理、配置、SQL 和对象设置、系统 DDL 映射。

了解 DDL 数据类型映射

将数据类型从 DDL 映射到 IRIS 时,常规参数和函数参数遵循以下规则:

  • 常规参数 - 这些在 DDL 数据类型和 IRIS 数据类型中以 %# 格式标识。例如:
     VARCHAR(%1)

映射到:

     %String(MAXLEN=%1)

因此,DDL 数据类型为:

     VARCHAR(10)

映射到:

  • 函数参数 — 当 DDL 数据类型中的参数必须经过一些转换才能放入 IRIS 数据类型中时,使用这些参数。这方面的一个例子是将 DDL 数据类型的数值精度和比例参数转换为 IRIS 数据类型的 MAXVALMINVALSCALE 参数。例如:

映射到:

数据类型 采用参数 和

0
0 148
文章 姚 鑫 · 六月 7, 2022 9m read

第二章 数据类型(一)

指定 SQL 实体(如列)可以包含的数据类型。

描述

此处描述了以下主题:

  • 支持的 DDL 数据类型及其类属性映射表

  • 数据类型优先级用于从具有不同数据类型的数据值中选择最具包容性的数据类型

  • 日期、时间、PosixTime 和时间戳数据类型

    • 使用SqlCategory和用户定义的标准
    • 对 1840 年 12 月 31 日之前的日期的可配置支持
  • 支持字符串数据类型、列表数据类型和流数据类型

  • 支持 ROWVERSION 数据类型

  • IRIS® 数据平台 ODBC / JDBC 公开的数据类型

  • 使用查询元数据方法和数据类型整数代码确定列的数据类型

  • 创建用户定义的数据类型

  • 处理未定义的数据类型

  • 数据类型转换函数

数据类型指定列可以保存的值的种类。在使用 CREATE TABLEALTER TABLE 定义字段时指定数据类型。定义 SQL 字段时,可以指定下表(左列)中列出的 数据类型。当指定其中一种 数据类型时,它会映射到右侧列中列出的IRIS 数据类型类。在IRIS 中定义字段时,可以指定 数据类型或数据类型类。 数据类型名称不区分大小写。数据类型类名称区分大小写。 数据类型类可以通过全名(例如,)或短名()来指定。

它们映射到的 数据类型和数据类型类通常提供不同的参数和参数默认值。

0
0 221
文章 姚 鑫 · 六月 3, 2022 2m read

第161章 SQL函数 YEAR

返回日期表达式的年份的日期函数。

大纲

YEAR(date-expression)

{fn YEAR(date-expression)}

参数

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

描述

YEAR 将日期整数($HOROLOG 日期)、 格式日期字符串或时间戳作为输入。 以整数形式返回相应的年份。

日期表达式时间戳可以是数据类型 (编码的 位有符号整数),也可以是数据类型 %Library.TimeStamp ()。

年份 () 部分应该是 到 范围内的四位整数。输入时前导零是可选的。前导零在输出上被抑制。两位数的年份不会扩展到四位数。

的日期部分经过验证,并且必须包含 到 12 范围内的月份以及指定月份和年份的有效日期值。否则,将生成 错误 。

如果日期表达式的时间部分存在,则对其进行验证,但可以省略。

注意:为了与 内部日期表示兼容,强烈建议将所有年份值表示为 到 范围内的四位整数。

和 SQL 函数支持“儒略日期”,可用于表示 0001 之前的年份。 提供了支持此类儒略日期的方法调用。

年份格式默认为四位数年份。要更改今年显示默认值,请使用带有 选项的 命令。

0
0 143
文章 姚 鑫 · 六月 2, 2022 4m read

第160章 SQL函数 XMLFOREST

格式化多个 XML 标记以包含表达式值的函数。

大纲

XMLFOREST(expression [AS tag][,expression [AS tag]])

参数

  • expression - 任何有效的表达式。通常是包含要标记的数据值的列的名称。当指定为逗号分隔列表时,列表中的每个表达式都将包含在其自己的 XML 标记标记中。
  • AS tag - 可选 — XML 标记标记的名称。如果指定了标签,则 AS 关键字是必需的。保留标签中字母的大小写。 用双引号括起来的标签是可选的。如果省略双引号,标签必须遵循 命名标准。用双引号括起来的标签消除了这些命名限制。

XMLFOREST 对有效的标签名称实施 命名标准。它不能包含任何字符,也不能包含空格字符,并且不能以 "-", , 或数字。

如果指定不带 AS 标记子句的表达式,则标记值是表达式列的名称(大写字母):。

描述

函数返回用其自己的 XML 标记开始标记和结束标记标记的每个表达式的值,如 tag 中指定的那样。例如, 返回如下值:IL。 不能用于生成空元素标记。

可用于引用表或视图的 查询或子查询。 可以与普通列值一起出现在 列表中。

返回指定的表达式值,由开始标记和结束标记括起来,格式如下:

0
0 203
文章 姚 鑫 · 六月 1, 2022 6m read

第159章 SQL函数 XMLELEMENT

一种格式化 XML 标记标记以包含一个或多个表达式值的函数。

大纲

XMLELEMENT([NAME] tag,expression[,expression])

XMLELEMENT([NAME] tag,XMLATTRIBUTES(expression [AS alias]),expression[,expression])

参数

  • NAME tag - XML标记的名称。NAME关键字是可选的。该参数有三种语法形式: , 和。前两者在功能上是相同的。如果指定,标记必须用双引号括起来。标签中的字母大小写保持不变。

XMLELEMENT不执行标记值的验证。然而,标准要求有效的标记名不能包含任何字符 ,并且不能以, 或数字开头。

如果指定没有标记值的 关键字, 将提供默认标记值:。 NAME 关键字不区分大小写;结果标签初始大写。

  • - 任何有效的表达式。通常是包含要标记的数据值的列的名称。可以指定以逗号分隔的列列表或其他表达式,所有这些都将包含在同一标记中。第一个以逗号分隔的元素可以是 XMLATTRIBUTES 函数。只能指定一个 元素。

描述

函数返回用标记中指定的 XML(或 HTML)标记开始标记和结束标记标记的表达式的值。例如, 返回如下值:。 不能用于生成空元素标记。

可用于引用表或视图的

0
0 260
文章 姚 鑫 · 五月 31, 2022 1m read

第158章 SQL函数 XMLCONCAT

注:IRIS函数。

连接 XML 元素的函数。

大纲

XMLCONCAT(XmlElement1,XmlElement2[,...])

参数

  • XmlElement - XMLELEMENT 函数。指定两个或多个要连接的 XmlElement

描述

XMLCONCAT 函数将来自多个 函数的值作为单个字符串返回。 可用于引用表或视图的 T 查询或子查询。 可以与普通字段值一起出现在 列表中。

示例

以下查询连接来自两个 函数的值:

SELECT Name,XMLCONCAT(XMLELEMENT("Para",Name),
                      XMLELEMENT("Para",Home_City)) AS ExportString
     FROM Sample.Person

以下查询将 嵌套在 函数中:

SELECT XMLELEMENT("Item",Name,
          XMLCONCAT(
              XMLELEMENT("Para",Home_City,' ',Home_State),
              XMLELEMENT("Para",'is residence')))
       AS ExportString
FROM Sample.Person
0
0 173
文章 姚 鑫 · 五月 30, 2022 4m read

第157章 SQL函数 WEEK

一个日期函数,它将一年中的第几周作为日期表达式的整数返回。

大纲

{fn WEEK(date-expression)}

参数

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

描述

WEEK 接受一个日期表达式,并返回该日期从年初开始的周数。

默认情况下,使用 $HOROLOG 日期(从 1840 年 12 月 31 日开始的正整数或负整数天数)计算周数。因此,周数是逐年计算的,因此第 1 周是完成从上一年最后一周开始的 7 天期间的天数。一周总是从星期日开始;因此,日历年的第一个星期日标志着从第 1 周到第 2 周的变化。如果一年中的第一个星期日是 1 月 1 日,则该星期日是第 1 周;如果一年中的第一个星期日晚于 1 月 1 日,则该星期日是第 2 周的第一天。因此,第 1 周的长度通常少于 7 天。可以使用 函数确定星期几。一年中的总周数通常为 53,闰年可能为 。

IRIS 还支持确定一年中星期的 ISO 8601 标准。该标准主要用于欧洲国家。当配置为 ISO 8601 时, 从星期一开始计算星期,并将星期分配给包含该星期星期四的年份。

0
0 184
文章 姚 鑫 · 五月 29, 2022 1m read

第156章 SQL函数 USER

返回当前用户的用户名的函数。

大纲

USER

{fn USER}
{fn USER()}

描述

USER 不接受任何参数并返回当前用户的用户名(也称为授权 ID)。通用函数不允许括号; 标量函数可以指定或省略空括号。

用户名是使用 命令定义的。

的典型用途是在 SELECT 语句选择列表或查询的 WHERE 子句中。在设计报告时, 可用于打印正在为其生成报告的当前用户。

示例

以下示例返回当前用户名:

SELECT USER AS CurrentUser

yx

以下示例选择姓氏 ( 或名字(没有中间首字母)与当前用户名匹配的那些记录:

SELECT Name FROM Sample.Person 
WHERE %SQLUPPER(USER)=%SQLUPPER($PIECE(Name,',',1)) 
OR %SQLUPPER(USER)=%SQLUPPER($PIECE($PIECE(Name,',',2),' ',1))
0
0 142
文章 姚 鑫 · 五月 28, 2022 2m read

第155章 SQL函数 UPPER

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

大纲

UPPER(expression)

UPPER expression

参数

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

描述

UPPER 函数将所有字母字符转换为大写字母。这是 LOWER 函数的反函数。 保留不变的数字、标点符号和前导或尾随空格。

不强制将数字解释为字符串。 SQL 从数字中删除前导零和尾随零。指定为字符串的数字保留前导零和尾随零。

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

$SYSTEM.SQL.Functions.UPPER(expression)

是字母大小写转换的标准函数,而不是排序规则。对于大写排序规则,使用 %SQLUPPER,它提供了数字、 值和空字符串的高级排序规则。

示例

以下示例返回所有名称,选择那些名称的大写形式以开头的名称:

SELECT Name
FROM Sample.Person
WHERE UPPER(Name) %STARTSWITH UPPER('JO')
0
0 176
文章 姚 鑫 · 五月 27, 2022 4m read

第154章 SQL函数 UNIX_TIMESTAMP

注:此函数IRIS可用,Cache不可用。

将日期表达式转换为 UNIX 时间戳的日期/时间函数。

大纲

UNIX_TIMESTAMP([date-expression])

参数

  • date-expression - 可选 — 作为列名称、另一个标量函数的结果或日期或时间戳文字的表达式。 UNIX_TIMESTAMP 不会从一个时区转换到另一个时区。如果省略 date-expression,则默认为当前 时间戳。

描述

返回一个 时间戳,即自 以来的秒数(和小数秒)。

如果不指定 ,则 默认为当前 时间戳。因此,假设系统范围的默认精度为 , 等效于 。

如果指定 , 会将指定的 值转换为 时间戳,计算该时间戳的秒数。 可以返回正数或负数秒数。

将其值作为数据类型 返回。它可以返回小数秒的精度。如果不指定 date-expression,它将采用当前配置的系统范围精度。如果指定 ,它将从 获取其精度。

日期表达式值

可选的日期表达式可以指定为:

  • ODBC 时间戳值(数据类型 %Library.TimeStamp):
  • 时间戳值(数据类型 ):编码的 64 位有符号整数。
  • 日期值(数据类型 ):自 1以来的天数,其中第 天是 。
  • 时间戳,带或不带小数秒:。

不进行时区转换:如果 为 UTC 时间,则返回 UTC UnixTime

0
0 361