文章
姚 鑫 · 三月 26, 2021 阅读大约需 6 分钟

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

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

返回完整结果集

使用%Execute()%ExecDirect()执行语句将返回一个实现%SQL.StatementResult接口的对象。该对象可以是单一值,结果集或从CALL语句返回的上下文对象。

%Display()方法

可以通过调用%SQL.StatementResult类的%Display()实例方法来显示整个结果集(结果对象的内容),如以下示例所示:

  DO rset.%Display()

请注意,%Display()方法不会返回%Status值。

显示查询结果集时,%Display()通过显示行数来结束:“受影响的5行”。 (这是%Display()遍历结果集之后的%ROWCOUNT值。)请注意,%Display()不会在此行计数语句之后发出行返回。

%Display()有两个可选参数:

  • 分隔符:在数据列和数据标题之间插入的字符串。它出现在结果集列之间,紧靠标题或数据值之前。默认为无定界符。如果省略,请在“列对齐”标志之前指定一个占位符逗号。
  • 列对齐:整数标志,指定如何计算数据列和数据标题之间的空格。可用的选项有:
    • 0:结果集标题/数据列将根据标准定界符(选项卡)对齐。这是默认值。
    • 1:结果集标题/数据列将根据列标题和标准定界符(标签)的长度对齐。
    • 2:结果集标题/数据列将根据列数据属性的精度/长度和标准定界符(选项卡)进行对齐。

%DisplayFormatted()方法

可以通过调用%SQL.StatementResult类的%DisplayFormatted()实例方法,而不是调用%Display(),将结果集内容重新格式化并重定向到生成的文件。

可以通过指定字符串选项%DisplayFormatted(“HTML”)或相应的整数代码%DisplayFormatted(1)来指定结果集格式。可以使用以下格式:XML(整数代码0),HTML(整数代码1),PDF(整数代码2),TXT(整数代码99)或CSV(整数代码100)。 (请注意,CSV格式未实现为真正的逗号分隔值输出;相反,它使用制表符来分隔列。)TXT格式(整数代码99)以行数结尾(例如,“受影响的5行”) ”);其他格式不包括行数。 InterSystems IRIS生成指定类型的文件,并附加适当的文件扩展名。

可以指定或省略结果集文件名:

  • 如果指定一个目标文件(例如,%DisplayFormatted(99,"myresults")),则在当前命名空间的子目录的mgr目录中生成具有该名称和相应后缀(文件扩展名)的文件。
    例如,C:\InterSystems\IRIS\mgr\user\myresults.txt.
    如果具有该后缀的指定文件已经存在,则InterSystems IRIS将用新数据覆盖它。
  • 如果没有指定目标文件(例如,%DisplayFormatted(99),则在Temp子目录的mgr目录中生成一个具有随机生成的名称和适当后缀(文件扩展名)的文件。
    例如,C:\InterSystems\IRIS\mgr\Temp\w4FR2gM7tX2Fjs.txt.
    每次运行一个查询时,都会生成一个新的目标文件。

这些例子显示了Windows文件名;
InterSystems IRIS支持其他操作系统上的等效位置。

如果无法打开指定的文件,则此操作将在30秒后超时并显示一条错误消息;否则,该操作将超时。当用户没有对指定目录(文件夹)的WRITE权限时,通常会发生这种情况。

如果无法以指定的格式呈现数据,则将创建目标文件,但不会将结果集数据写入其中。而是将适当的消息写入目标文件。例如,流字段OID包含与XML和HTML特殊格式字符冲突的字符。可以通过在流字段上使用XMLELEMENT函数来解决此XML和HTML流字段问题。例如SELECT Name,XMLELEMENT(“ Para”,Notes)

可以选择提供%DisplayFormatted()在执行指定格式转换时将使用的转换表的名称。

如果一个结果集序列中有多个结果集,则每个结果集的内容都将写入其自己的文件中。

可选的第三个%DisplayFormatted()参数指定消息存储在单独的结果集中。成功完成后,将返回类似以下的消息:

Message
21 row(s) affected.

下面的Windows示例在C:\InterSystems\IRIS\mgr\user\中创建了两个PDF(整数代码2)结果集文件。
它为消息创建一个mess结果集,然后使用%Display()将消息显示到终端:

/// d ##class(PHA.TEST.SQL).CreatePDF()
ClassMethod CreatePDF()
{

    SET myquery=2
    SET myquery(1)="SELECT Name,Age FROM Sample.Person"
    SET myquery(2)="WHERE Age > ? AND Age < ? ORDER BY Age"
    SET rset = ##class(%SQL.Statement).%ExecDirect(,.myquery,12,20)
    IF rset.%SQLCODE'=0 {
        WRITE !,"1st ExecDirect SQLCODE=",rset.%SQLCODE,!,rset.%Message  QUIT
    }
    DO rset.%DisplayFormatted(2,"Teenagers",.mess)
    DO mess.%Display()
    WRITE !,"End of teen data",!!
    SET rset2 = ##class(%SQL.Statement).%ExecDirect(,.myquery,19,30)
    IF rset2.%SQLCODE'=0 {
        WRITE !,"2nd ExecDirect SQLCODE=",rset2.%SQLCODE,!,rset2.%Message  QUIT
    }
    DO rset2.%DisplayFormatted(2,"Twenties",.mess)
    DO mess.%Display()
    WRITE !,"End of twenties data"
}
DHC-APP>d ##class(PHA.TEST.SQL).CreatePDF()
Message
9 row(s) affected.

End of teen data

Message
20 row(s) affected.

End of twenties data
/// d ##class(PHA.TEST.SQL).CreatePDF1()
ClassMethod CreatePDF1()
{
      ZNSPACE "SAMPLES"
  SET myquery=2
  SET myquery(1)="SELECT Name,Age FROM Sample.Person"
  SET myquery(2)="WHERE Age > ? AND Age < ? ORDER BY Age"
  SET rset = ##class(%SQL.Statement).%ExecDirect(,.myquery,12,20)
  DO rset.%DisplayFormatted(2,"Teenagers")
  WRITE !,"End of teen data",!!
  SET rset2 = ##class(%SQL.Statement).%ExecDirect(,.myquery,19,30)
  DO rset2.%DisplayFormatted(2,"Twenties")
  WRITE !,"End of twenties data"
}
DHC-APP>d ##class(PHA.TEST.SQL).CreatePDF1()

End of teen data


End of twenties data

对结果集进行分页

可以使用一个视图ID (%VID)来分页结果集。下面的例子从结果集中返回页面,每个页面包含5行:

/// d ##class(PHA.TEST.SQL).Paginating()
ClassMethod Paginating()
{
    SET q1="SELECT %VID AS RSRow,* FROM "
    SET q2="(SELECT Name,Home_State FROM Sample.Person WHERE Home_State %STARTSWITH 'M') "
    SET q3="WHERE %VID BETWEEN ? AND ?"
    SET myquery = q1_q2_q3
    SET tStatement = ##class(%SQL.Statement).%New()
    SET qStatus=tStatement.%Prepare(myquery)
    IF qStatus'=1 {
        WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT
    }
    FOR i=1:5:25 {
        WRITE !!,"Next Page",!
        SET rset=tStatement.%Execute(i,i+4)
        DO rset.%Display()
    }
}
DHC-APP>d ##class(PHA.TEST.SQL).Paginating()


Next Page
RSRow   Name    Home_State
1       O'Rielly,Chris H.       MS
2       Orwell,John V.  MT
3       Zevon,Heloisa O.        MI
4       Kratzmann,Emily Z.      MO
5       King,Dmitry G.  MO

5 Rows(s) Affected

Next Page
RSRow   Name    Home_State
6       Hanson,George C.        MD
7       Martinez,Emilio G.      MO
8       Cheng,Charlotte Y.      MI
9       Emerson,Edgar T.        MO
10      Nelson,Neil E.  MT

5 Rows(s) Affected

Next Page
RSRow   Name    Home_State
11      Larson,Nataliya Z.      MD
12      Lennon,Chelsea T.       MD
13      Ingleman,Kristen U.     MT
14      Zucherro,Olga H.        MN
15      Ng,Lola H.      MD

5 Rows(s) Affected

Next Page
RSRow   Name    Home_State
16      Frost,Xavier D. MO
17      Adams,Diane F.  MD
18      Isaacs,Chad N.  MN
19      Van De Griek,Phil S.    MS
20      Schaefer,Usha G.        MO

5 Rows(s) Affected

Next Page
RSRow   Name    Home_State
21      Wells,Sophia U. MS
22      Vivaldi,Michelle N.     MD
23      Anderson,Valery N.      MD
24      Frost,Heloisa K.        MI
25      Gallant,Thelma Q.       MA

5 Rows(s) Affected
00
1 0 0 5
Log in or sign up to continue