文章
姚 鑫 · 三月 28 阅读大约需 7 分钟

第十三章 使用动态SQL(六)

第十三章 使用动态SQL(六)

%ObjectSelectMode = 1 Swizzling字段名称属性

下面的示例使用%ObjectSelectMode = 1进行准备,当使用字段名称属性返回值时,其类型类别为可Swizzle类型的字段(持久性类,序列类或流类)将自动发生Swizzle。转换字段值的结果是相应的对象参考(oref)。使用%Get()%GetData()方法访问字段时,InterSystems IRIS不会执行此筛选操作。在此示例中,rset.Home处于Swizzle状态,而引用同一字段的rset.%GetData(2)处于not swizzled状态:

/// d ##class(PHA.TEST.SQL).PropSQL2()
ClassMethod PropSQL2()
{
    SET myquery = "SELECT TOP 5 Name,Home FROM Sample.Person"
    SET tStatement = ##class(%SQL.Statement).%New(0)
    SET tStatement.%ObjectSelectMode=1
    WRITE !,"set ObjectSelectMode=",tStatement.%ObjectSelectMode,!
    SET qStatus = tStatement.%Prepare(myquery)
    IF qStatus'=1 {
        WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
    }
    SET rset = tStatement.%Execute()
    WHILE rset.%Next() {
        WRITE "Row count ",rset.%ROWCOUNT,!
        WRITE rset.Name
        WRITE " ",rset.Home,!
        WRITE rset.%GetData(1)
        WRITE " ",$LISTTOSTRING(rset.%GetData(2)),!!
    }
    WRITE !,"End of data"
    WRITE !,"Total row count=",rset.%ROWCOUNT
}

DHC-APP> d ##class(PHA.TEST.SQL).PropSQL2()

set ObjectSelectMode=1
Row count 1
yaoxin 5@Sample.Address
yaoxin 889 Clinton Drive,St Louis,WI,78672

Row count 2
xiaoli 5@Sample.Address
xiaoli

Row count 3
姚鑫 5@Sample.Address
姚鑫

Row count 4
姚鑫 5@Sample.Address
姚鑫

下面的示例使用%ObjectSelectMode = 1从唯一记录ID(%ID)导出所选记录的Home_State值。请注意,在原始查询中未选择Home_State字段:

/// d ##class(PHA.TEST.SQL).PropSQL2()
ClassMethod PropSQL2()
{
    SET myquery = "SELECT TOP 5 %ID AS MyID,Name,Age FROM Sample.Person"
    SET tStatement = ##class(%SQL.Statement).%New()
    SET tStatement.%ObjectSelectMode=1
    SET qStatus = tStatement.%Prepare(myquery)
    IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
    SET rset = tStatement.%Execute()
    WHILE rset.%Next() {
        WRITE rset.Name
        WRITE " Home State:",rset.MyID.Home.State,!
    }
    WRITE !,"End of data"
    WRITE !,"Total row count=",rset.%ROWCOUNT
}

DHC-APP>d ##class(PHA.TEST.SQL).PropSQL2()
yaoxin Home State:WI
xiaoli Home State:
姚鑫 Home State:
姚鑫 Home State:
姚鑫 Home State:

End of data
Total row count=5

如果已配置,则如果配置了swizzled属性,但系统无法生成引用,则系统会生成<SWIZZLE FAIL>错误。如果引用的属性已从磁盘中意外删除或被另一个进程锁定,则会发生这种情况。要确定SWIZZLE失败的原因,请在<SWIZZLE FAIL>错误之后立即在%objlasterror中查找并解码此%Status值。

默认情况下,未配置<SWIZZLE FAIL>。可以通过设置SET ^%SYS("ThrowSwizzleError")=1或使用InterSystems IRIS管理门户来全局设置此行为。在“系统管理”中,选择“配置”,然后选择“ SQL和对象设置”,然后选择“对象”。在此屏幕上,可以设置<SWIZZLE FAIL>选项。

%Get("fieldname")方法

可以使用%Get(“ fieldname”)实例方法按字段名称或字段名称别名返回数据值。 Dynamic SQL根据需要解析字母大小写。如果指定的字段名称或字段名称别名不存在,系统将生成<PROPERTY DOES NOT EXIST>错误。

下面的示例从查询结果集中返回Home_State字段和Last_Name别名的值。

/// d ##class(PHA.TEST.SQL).PropSQL4()
ClassMethod PropSQL4()
{
    SET myquery = "SELECT TOP 5 Home_State,Name AS Last_Name FROM Sample.Person"
    SET tStatement = ##class(%SQL.Statement).%New(2)
    SET qStatus = tStatement.%Prepare(myquery)
    IF qStatus'=1 {
        WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
    }
    SET rset = tStatement.%Execute()
    WHILE rset.%Next() {
        WRITE rset.%Get("Home_State")," : ",rset.%Get("Last_Name"),!
    }
    WRITE !,"End of data"
    WRITE !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQL).PropSQL4()
WI : yaoxin
 : xiaoli
 : 姚鑫
 : 姚鑫
 : 姚鑫

End of data
Total row count=5

必须使用%Get("fieldname")实例方法从使用%PrepareClassQuery()准备的现有查询中按字段属性名称检索单个数据项。如果字段属性名称不存在,则系统会生成<PROPERTY DOES NOT EXIST>错误。

下面的示例从内置查询中按字段属性名称返回Nsp(命名空间)字段值。因为此查询是现有的存储查询,所以此字段检索需要使用%Get("fieldname")方法。请注意,由于“Nsp”是属性名称,因此区分大小写:

/// d ##class(PHA.TEST.SQL).PropSQL5()
ClassMethod PropSQL5()
{
    SET tStatement = ##class(%SQL.Statement).%New(2)
    SET qStatus = tStatement.%PrepareClassQuery("%SYS.Namespace","List")
    IF qStatus'=1 {
        WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
    }
    SET rset = tStatement.%Execute()
    WHILE rset.%Next() {
        WRITE "Namespace: ",rset.%Get("Nsp"),!
    }
    WRITE !,"End of data"
    WRITE !,"Total row count=",rset.%ROWCOUNT
}
DHC-APP>d ##class(PHA.TEST.SQL).PropSQL5()
Namespace: %SYS
Namespace: DHC-APP
Namespace: DHC-CHSSWEB
Namespace: DHC-CSM
Namespace: DHC-DATA
Namespace: DHC-DWR
Namespace: DHC-EKG
Namespace: DHC-HEIS
Namespace: DHC-HR
Namespace: DHC-LISDATA
Namespace: DHC-LISSRC
Namespace: DHC-MEDSRC
Namespace: DHC-MRQ
Namespace: DOCBOOK
Namespace: FDBMS
Namespace: PACS
Namespace: PIS
Namespace: RIS
Namespace: SAMPLES
Namespace: USER

End of data
Total row count=20

重复名称:如果名称解析为相同的属性名称,则它们是重复的。重复名称可以是对同一字段的多个引用,对表中不同字段的引用或对不同表中字段的引用。如果SELECT语句包含相同字段名称或字段名称别名的多个实例,则%Get(“fieldname”)始终返回查询中指定的重复名称的最后一个实例。这与rset.PropName相反,后者返回查询中指定的重复名称的第一个实例。在下面的示例中显示:

/// d ##class(PHA.TEST.SQL).PropSQL6()
ClassMethod PropSQL6()
{
    SET myquery = "SELECT c.Name,p.Name FROM Sample.Person AS p,Sample.Company AS c"
    SET tStatement = ##class(%SQL.Statement).%New()
    SET qStatus = tStatement.%Prepare(myquery)
    IF qStatus'=1 {
        WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
    }
    SET rset = tStatement.%Execute()
    WHILE rset.%Next() {
        WRITE "Prop=",rset.Name," Get=",rset.%Get("Name"),! 
    }
    WRITE !,rset.%ROWCOUNT," End of data"
}

%GetData(n)方法

%GetData(n)实例方法返回由结果集的整数计数列号索引的当前行的数据您可以将%GetData(n)与使用%Prepare()准备的指定查询或使用%PrepareClassQuery()准备的存储查询一起使用。

使用%PrepareClassQuery()准备。
整数n对应于查询中指定的选择项列表的序列。除非在选择项列表中明确指定,否则不会为RowID字段提供整数n值。如果n大于查询中的选择项数,或者为0,或者为负数,则Dynamic SQL不返回任何值,也不发出错误。

%GetData(n)是返回特定重复字段名称或重复别名的唯一方法; rset.Name返回第一个重复项,%Get(“Name”)返回最后一个重复项。

java
/// d ##class(PHA.TEST.SQL).PropSQL7()
ClassMethod PropSQL7()
{
SET myquery="SELECT TOP 5 Name,SSN,Age FROM Sample.Person"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {
WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
}
SET rset = tStatement.%Execute()
WHILE rset.%Next() {
WRITE "Years:",rset.%GetData(3)," Name:",rset.%GetData(1),!
}
WRITE "End of data"
WRITE !,"Total row count=",rset.%ROWCOUNT
}

java
DHC-APP>d ##class(PHA.TEST.SQL).PropSQL7()
Years:30 Name:yaoxin
Years: Name:xiaoli
Years:7 Name:姚鑫
Years:7 Name:姚鑫
Years:43 Name:姚鑫
End of data
Total row count=5

返回多个结果集

CALL语句可以将多个动态结果集作为一个集合返回,称为结果集序列(RSS)。

下面的示例使用%NextResult()方法分别返回多个结果集:

/// d ##class(PHA.TEST.SQL).PropSQL8()
ClassMethod PropSQL8()
{
    SET mycall = "CALL Sample.CustomSets()"
    SET rset = ##class(%SQL.Statement).%ExecDirect(,mycall)
    IF rset.%SQLCODE'=0 {
        WRITE !,"ExecDirect SQLCODE=",rset.%SQLCODE,!,rset.%Message  QUIT
    }
    SET rset1=rset.%NextResult()
    DO rset1.%Display()
    WRITE !,"End of 1st Result Set data",!!
    SET rset2=rset.%NextResult()
    DO rset2.%Display()
    WRITE !,"End of 2nd Result Set data"
}
DHC-APP> d ##class(PHA.TEST.SQL).PropSQL8()
ID      Name    Street  City    State   Spouse
3       Davis,Robert I. 4177 Franklin Court     Fargo   WY      86
2       Hanson,Roberta O.       9840 Ash Drive  Boston  KS      155
4       Huff,Olga M.    1902 Franklin Avenue    Vail    DE      150
1       Woo,Jocelyn A.  9932 Clinton Avenue     Queensbury      NM      14
5       Zubik,George T. 8102 First Drive        Denver  VA      110

5 Rows(s) Affected
End of 1st Result Set data

ID      Name    Street  City    State   Spouse
5       Campos,Alvin N. 1847 Franklin Drive     Ukiah   WY      206
1       Fripp,Kristen A.        1487 Ash Place  Islip   NC      133
3       Jafari,Christen K.      7384 Washington Court   Newton  CO      168
4       Kratzmann,Mark V.       9573 Second Blvd        Chicago OR      43
2       O'Donnell,George H.     3413 Main Drive Newton  RI      143
7       Ravazzolo,Danielle Y.   2898 Clinton Blvd       Tampa   HI      133
10      Rodriguez,Sophia U.     4766 Clinton Avenue     Ukiah   AR      202
6       Sverdlov,Phyllis J.     5010 Oak Place  Fargo   VT      214
8       Uhles,Andrew O. 4931 Madison Street     Bensonhurst     IA      129
9       Xerxes,Mo C.    49 Main Drive   Vail    CA      151

10 Rows(s) Affected
End of 2nd Result Set data
00
1 0 0 22
Log in or sign up to continue