InterSystems ObjectScript 技巧与窍门
嘿,社区的朋友们大家好!
是的,我知道我们有很多技巧和窍门类的文章-——我们甚至为此专门设置了一个标签(Tips & Tricks),不是吗?但我不能分享我自己的收藏。在这个合集中,您可以找到适合初学者的代码片段,以及一些日常的 ObjectScript 结构。事实上,这也是一种学习我最喜欢的编程语言的新方法。所以,如果你们有什么要补充的,欢迎提出!
1) 使用格式文本返回错误:
Return $$$ERROR($$$GeneralError, $$$FormatText("Failed to open message with ID = %1", id))2) 使用嵌入式 SQL 时的错误检查 (&sql()):
Return:SQLCODE<0 $$$ERROR($$$GeneralError, $$$FormatText("Operation failed. SQLCODE = %1: %2", SQLCODE, $SYSTEM.SQL.Functions.SQLCODE(SQLCODE)))3) 空性检查,包括任何类似空值的值:
If $ASCII(object.field)>0 {
// Not empty
}这里需要解释一下,我相信。例如,通过 SOAP 协议的外部系统可以将空值返回为 $CHAR(0)。在 Cache null 中,它是一个空字符串,但检查空字符串将无法正常工作。该表达式是解决这一问题的单行方法。
4) 在表中自动填充记录更新时间戳:
Property UpdatedAt As %TimeStamp [ SqlComputeCode = { Set {*} = $ZDATETIME($NOW(), 3) }, SqlComputed, SqlComputeOnChange = (%%INSERT, %%UPDATE) ];5)从 LookupTable 读取值(名为 Settings):
Set value = $GET(^Ens.LookupTable("Settings", "my_key"))6) 将值写入 LookupTable (名为 Settings):
Set tSC = ##class(Ens.Util.LookupTable).%UpdateValue("Settings", "my_key", value)7) 导入 Python 软件包:
XData %import [ MimeType = application/python ]
{
import iris
from confluent_kafka import Consumer, KafkaException, TopicPartition, KafkaError
}8)从 Python 返回 IRIS 状态:
return iris.system.Status.OK()
return iris.system.Status.Error(5001, f'Request body is invalid: {e}')9) Python 代码中的跟踪:
Method Trace(message As %String)
{
$$$TRACE(message)
}
Method PyImpl() [ Language = python ]
{
self.Trace(f'Received message: {input.value}')
}10) 将 JSON 数组 (%DynamicArray) 转换为逗号分隔字符串并返回:
Set jsonArray = ["test1","test2","test3"]
Set str = $TRANSLATE(jsonArray.%ToJSON(), "[]")
Set jsonArray = [].%FromJSON("["_str_"]")11)格式化 JSON:
Do ##class(%JSON.Formatter).%New().FormatToString({"test":"test"}, .formatted)12)将 %Status 转换为异常并返回 Try/Catch:
try {
$$$ThrowOnError(object.%Save())
} catch ex {
Return ex.AsStatus()
}13)将 $$ERROR 写入应用程序错误日志(当我们需要 "无声 "异常时):
Do ##class(%Exception.StatusException).CreateFromStatus(tSC).Log()14)对输入字符串进行规范化处理:
Set value = $ZSTRIP(value, "<>WC")15)迭代 %DynamicArray 的一种方法:
Set it = array.%GetIterator()
While it.%GetNext(.key, .value) {
Write !, key, ":", value
}16)执行 SQL 查询的一种方法:
Set rs = ##class(%SQL.Statement).%ExecDirect(, "SELECT ID, Name FROM MyTable WHERE Status = ?", status)
Return:rs.%SQLCODE<0 $$$ERROR($$$GeneralError, $$$FormatText("Execute failed. SQLCODE = %1: %2", rs.%SQLCODE, rs.%Message))
While rs.%Next() {
Write !, rs.ID_", "_rs.Name
}17)执行 SQL 查询的另一种方法(使用游标):
&sql(DECLARE C1 CURSOR FOR SELECT ID, Name INTO :id, :name FROM MyTable WHERE Status = :status)
&sql(OPEN C1)
Return:SQLCODE $SYSTEM.Error.FromSQLCode(SQLCODE, %msg).Status
&sql(FETCH C1)
While SQLCODE = 0 {
Write !, $$$FormatText("id = %1, name = %2", id, name)
&sql(FETCH C1)
}
&sql(CLOSE C1)18) 执行 SQL 查询的第三种方法(使用 SQL 函数):
Query Test(status As %String) As %SQLQuery [ SqlProc ]
{
SELECT ID, Name FROM MyTable WHERE Status = :status
}
ClassMethod TestRun()
{
Set rs = ..TestFunc("Active")
While rs.Next() {
Write !, rs.ID_", "_rs.Name
}
}以上是主要的三种方法,但还有其他执行 SQL 查询的方法。这里就不一一列举了,我们继续往下看。
19)在单个实例中运行代码,无论哪个进程先到(锁定):
Lock +^MyLock(id):0
Return:'$TEST $$$OK
Try {
// Parallel execution is prohibited for this block
} Catch ex {
Set tSC = ex.AsStatus()
}
Lock -^MyLock(id)20) $CASE 或 $SELECT 代替 If/Else 链:
Set label = $CASE(status, "A":"Active", "I":"Inactive", "P":"Pending", :"Unknown")
Set label = $SELECT(status="A": "Active", status="I": "Inactive", status="P":"Pending", 1:"Unknown")21) 临时(进程私有)全局:
Set ^||Temp(1) = "Will be removed automatically when the process ends"22) 添加前导零:
Return $REPLACE($JUSTIFY(docNumber,4)," ",0)23) 在 JSON 对象中设置数值字段:
Set json = {"id":(+value)}24) 在 JSON 对象中设置布尔字段:
Do json.%Set("active", isActive, "boolean")25) 条件中 AND 的替代方法 (&&):
If '$ISOBJECT(obj),obj.prop'="" {
Write !, obj.prop
}26) 对数组进行迭代(Globals 也是如此):
Set node = ""
For {
Set node = $ORDER(array(node))
Quit:node=""
Set subnode = ""
For {
Set subnode = $ORDER(array(node,subnode))
Quit:subnode=""
Write !, "array(", "node, ",", subnode, ") = ", array(node,subnode)
}
}27)动态全局名称:
Set MyGlobal = "^Sample.Data"
Write !, $GET(@MyGlobal@(node))28) 轮到你了! 🙂