Net.Data 提供了关系数据库语言环境,帮助您访问关系数据资源。您提供的 用来访问关系数据的 SQL 语句,将作为动态 SQL 执行。有关动态 SQL 的详情, 参见数据库文档。
以下章节描述语言环境以及如何使用这些语言环境:
开放数据库连接 (ODBC) 语言环境通过一个 ODBC 接口执行 SQL 语句。ODBC 是 基于 X/Open SQL CAE 规格说明的,它允许单一的应用访问多个数据库管理系统。
要使用 ODBC 语言环境:
要使用 ODBC 语言环境,首先应获取并安装 ODBC 驱动程序和驱动程序管理器。您的 ODBC 驱动程序文档描述了如何安装和配置 ODBC 环境。
验证 Net.Data 初始化文件中是否有类似如下的配置语句,并且在一行上。
注意: | 以下示例中的路径可能因操作系统的不同而有所变化。 |
ENVIRONMENT (DTW_ODBC) d:/net.data/lib/dtwodbc.dll ( IN DATABASE, LOGIN, PASSWORD, TRANSACTION_SCOPE, START_ROW_NUM, DTW_SET_TOTAL_ROWS)
限制:
您使用的数据库可能有不同的限制;请参考您的数据库文档以确定对该数据库的限制是否有所不同。
Oracle 语言环境提供了对 Oracle 数据的本机访问。可以在使用 CGI、FastCGI、NSAPI、 ISAPI 或 APAPI 时,从 Net.Data 访问 Oracle 数据库。此语言环境支持 Oracle 8.1.5。
要使用 Oracle 语言环境,验证初始化文件中是否有以下配置语句,并且是在一行上。
注意: | 此配置语句中的路径可能因操作系统或设置而有所不同。 |
ENVIRONMENT (DTW_ORA) /net.data/lib/dtwora.so ( IN DATABASE, LOGIN, PASSWORD, TRANSACTION_SCOPE, START_ROW_NUM, DTW_SET_TOTAL_ROWS)
参见设置 Oracle 语言环境以了解如何进一步设置 Oracle 语言环境。
限制:
LOGIN=admin@ora73
SQL 语言环境提供了对 DB2 数据库的访问。在访问 DB2 时,使用此语言环境以获得最佳的性能。
要使用 SQL 语言环境,验证初始化文件中是否有以下配置语句,并且是在一行上。
注意: | 此配置语句中的路径可能因操作系统或设置而有所不同。 |
ENVIRONMENT (DTW_SQL) d:/net.data/lib/dtwsql.dll (IN DATABASE, LOGIN, PASSWORD, TRANSACTION_SCOPE, START_ROW_NUM, DTW_SET_TOTAL_ROWS)
嵌套的 SQL 语句
可以调用在另一个 SQL 函数中的 SQL 函数。如果传送了表,则应确保在每个函数中使用唯一的表名;否则,可能会出现意外的结果。
示例:从 ROW 块或另一个 SQL 函数调用 SQL 函数
%define mytable1 = %TABLE %define mytable2 = %TABLE %FUNCTION(DTW_SQL) sql2 (IN p1, OUT t2) { select * from NETDATA.STAFFINF where projno='$(p1)' %REPORT { %ROW { $(N1) is $(V1) %} %} %} %FUNCTION(DTW_SQL) sql1 (OUT t1) { select * from NETDATA.STAFFINF %REPORT { %ROW { @sql2(V1, mytable2) %} %} %} %HTML(netcall1) { @sql1(mytable1) %}
限制:
您使用的数据库可能有不同的限制;请参考您的数据库文档以确定对该 DBMS 的限制是否有所不同。
如果使用正确,参数标记可通过允许 DB2 利用其高速缓存来提高查询的性能。在 SQL 语句中, 参数标记是一个问号 (?),指示在执行该语句时替代应用程序提供的值的位置。该值是从 Net.Data SQL 函数定义的参数列表上的 Net.Data 变量获得的。获取这些值的方式依据使用参数标记的方式而定。
可以两种方式来使用参数标记:
显式使用参数标记:
在创建 SQL 语句时,可将参数标记人工添加至查询。
例如:
%FUNCTION (DTW_SQL) select_staff(in id, in dept){ select * from staff where id = ? and dept = ? and salary = 35,000%}
对于每个参数标记,DTW_SQL 函数中都会有一个对应的 IN 参数。对于 SQL 和函数参数列表, 映射次序都是从左至右。未与 SQL 参数标记相关联的函数参数可放在函数参数列表的末尾。
隐式使用参数标记:
通过在初始化文件或宏中设置以下标志:DTW_USE_DB2_PREPARE_CACHE = YES,以便隐式使用参数标记。如果“DB2 准备高速缓存” 配置变量被设置为 YES,Net.Data 会将 SQL 语句中的每个变量替换为参数标记。数据被绑定至每个参数标记, 且不会从 Net.Data 参数列表传送出来(就好象显式使用参数标记一样)。
例如:
%FUNCTION (DTW_SQL) select_staff() { select * from staff where id = $(ID) and dept = $(dept) and salary = 35,000%}
限制:
当使用 insert、delete 或 update 语句修改数据库的内容时,只有当数据库接收到来自 Net.Data 的提交语句,这些修改才会变为永久性的修改。如果发生错误,Net.Data 将向数据库发送一个回滚语句,撤销上一次提交之后所作的全部修改。
Net.Data 发送提交和可能的回滚语句的方式取决于 TRANSACTION_SCOPE 的设置以及宏中是否显式地指定了提交语句。TRANSACTION_SCOPE 的值可以是 MULTIPLE 和 SINGLE。缺省值为 MULTIPLE。要将 TRANSACTION_SCOPE 设置为 SINGLE,使用 %DEFINE 语句或者调用 @DTW_ASSIGN(),并对适当的 LE 传送 ENVIRONMENT 语句上的变量。有关详情,参见本书第二章中的『定制 Net.Data 初始化文件』。
指定 Net.Data 在每个成功完成的 SQL 语句后都发出一个提交语句。如果 SQL 语句返回错误,则发出一个回滚语句。SINGLE 事务作用域确保了数据库修改的立即性;但是使用此作用域之后, 今后就不可能使用回滚语句来撤销所做的修改。
指定 Net.Data 将在发出提交语句之前执行所有的 SQL 语句。Net.Data 在请求的最后发送提交,如果每个 SQL 语句都已成功发出,提交将使数据库中所有的修改都变为永久性的修改。如果任何一个语句返回错误,则 Net.Data 就会在产生错误时发出回滚语句,该语句将把数据库设置回先前的状态。
保持 TRANSACTION_SCOPE 设置为 MULTIPLE 的状态并在您觉得可以作为一个事务来对待的每组语句的最后发出提交语句,这样, 您这个应用程序开发者就可以对应用程序中的提交和回滚行为进行完全的控制。例如,在每次对宏进行更新之后发出提交语句将有助于确保数据的完整性。
要发出 SQL 提交语句,可以定义一个能在 HTML 块中任意位置调用的函数:
%FUNCTION(DTW_SQL) user_commit() { commit %} ... %HTML { ... @user_commit() ... %}
限制:
在连接数据库之后,便不能更改 TRANSACTION_SCOPE 的设置。因此,宏中的所有 SQL 事务都属于同一处理过程。
如果使用 Net.Data 作为 Net.Commerce 的一部分,则需注意,Net.Commerce 有它自己的事务处理,并禁用了 Net.Data 的事务处理。
可以将大对象文件 (LOB) 存储在 DB2 数据库中,并使用 Net.Data SQL 或 ODBC 语言环境 来将它们合并成动态的 Web 页面。
当语言环境执行 SQL SELECT 语句或者返回 LOB 的存储过程时,它不会为 V(n) 表处理变量或 Net.Data 表字段指定对象。然而,它将 LOB 存储在 一个由 Net.Data 创建的文件中,并且只在 V(n) 表处理变量或 Net.Data 表字段中返回该文件的名称。在 Net.Data 宏中,可以使用名称来引用 LOB 文件;例如,可以通过超文本引用来创建 HTML 锚元素或者包含该文件的 URL 的映象元素。Net.Data 将包含 LOB 的文件放在由 HTML_PATH 配置变量指定的目录中,这些配置变量位于 Net.Data 初始化文件 (db2www.ini) 中。对 LOB 文件的写访问权仅限于与检索 LOB 的 Net.Data 请求相关联的用户标识。
LOB 的文件名是动态构造的,并且具有以下格式:
name[.extension]
其中:
扩展名 | 对象类型 |
---|---|
.bmp | 位图图像 |
.gif | 图形图像格式 |
.jpg | 联合图像专家组 (JPEG) 图像 |
.tif | 带有标记的图像文件格式 |
.ps | PostScript |
.mid | 乐器数字界面 (midi) 音频 |
.aif | AIFF 音频 |
.avi | 音频视频交错音频 |
.au | 基本音频 |
.ra | 实际音频 |
.wav | windows 音频视频 |
可移植文档格式 | |
.rmi | midi 序列 |
如果不能识别 BLOB 的对象类型,则不会为文件名添加扩展名。
当 Net.Data 返回包含 LOB 的文件名时,它将使用以下语法来为文件名添加前缀 /tmplobs/:
/tmplobs/name.[extension]
此前缀允许您在不是 Web 服务器的文档根目录的目录中查找 LOB 目录。
要确保正确地解析对 LOB 文件的引用,应将以下 Pass 伪指令添加到 Web 服务器的配置文件中:
Pass /tmplobs/* <full_path>/tmplobs/*
<full_path> 是在 Net.Data 初始化文件中为 HTML_PATH 配置变量指定的值。
计划提示: 返回 LOB 的每次查询都会导致在由 HTML_PATH 路径配置变量指定的目录中创建文件。在使用 LOB 时请考虑系统限度,因为它们会很块地消耗资源。您可能想定期清理目录,或者执行 dtwclean 守护程序。有关详情,参见管理临时 LOBS。建议您使用 DataLinks,它不需要由 SQL 语言环境来将文件存储在目录中,从而获得更好的性能并且使用更少的系统资源。
示例: 以下应用程序使用 MPEG 音频 (.mpa) 文件。因为 SQL 语言环境不识别此文件类型,所以使用 EXEC 变量来将 .mpa 扩展名追加到文件名中。此应用程序的用户必须单击文件名才能调用 MPEG 音频文件查看器。
%DEFINE{ lobdir="/u/IBMUSER/tmplobs"" myFile=%EXEC "rename $(lobdir)$(filename) $(lobdir)$(filename).mpa" %} %{ where rename is the command on your operating system to rename files %} %FUNCTION(DTW_SQL) queryData() { SELECT Name, IDPhoto, Voice FROM RepProfile %REPORT{ <p>Here is the information you selected:</p> %ROW{ @DTW_ASSIGN(filename, @DTW_rSUBSTR(V3, @DTW_rLASTPOS("/", V3))) $(myFile) $(V1) <img src="$(V2)"> <a href="$(V3).mpa">Voice sample</a><p> %} %} %} %HTML (Report){ @queryData() %}
如果 RepProfile 表中包含关于 Kinson Yamamoto 和 Merilee Lau 的信息,则执行 REPORT 块时将把以下 HTML 添加到所生成的 Web 页面中:
<p>Here is the information you selected:</p> Kinson Yamamoto <img src="/tmplobs/p2345n1.gif"> <a href="/tmplobs/p2345n2.mpa">Voice sample</a><p> Merilee Lau <img src="/tmplobs/p2345n3.gif"> <a href="/tmplobs/p2345n4.mpa">Voice sample</a><p>
先前示例中的 REPORT 块使用隐式表变量 V1、V2 和 V3。
对 LOB 的访问权:
在所提供的 Net.Data 初始化文件中,LOB 的缺省 tmplobs 目录在由 HTML_PATH 指定的目录下面。任何用户标识都可以访问它。如果更改了 HTML_PATH 值,则应确保运行 Web 服务器的用户标识对于由 HTML_PATH 指定的目录具有写访问权(有关详情,参见HTML_PATH)。
管理临时 LOB:
Net.Data 将临时 LOB 存储在一个称为 tmplobs 的子目录中,该子目录在 HTML_PATH 路径配置变量指定的目录下面。这些文件可能很大,应该定期清除,以便维持满意的性能。
Net.Data 提供了一个称为 dtwclean 的守护程序,它可以帮助您定期管理 tmplobs 目录。dtwclean 使用端口 7127。
要运行 dtwclean 守护程序: 在命令行窗口中输入以下命令:
dtwclean [-t xx] [-d|-l]
其中:
存储过程就是存储在数据库中、可以执行 SQL 语句的已编译程序。在 Net.Data 中,存储过程是使用 CALL 语句来从 Net.Data 函数中调用的。存储过程参数是从 Net.Data 函数的参数列表中传送来的。可以使用存储过程来改进性能和完整性,即,通过对数据库服务器保持已编译的 SQL 语句来实现。Net.Data 通过 SQL 和 ODBC 语言环境来支持将存储过程与 DB2 配合使用。Oracle 存储过程是通过 Oracle 语言环境来支持的。对于特定的 DB2,Net.Data 支持存储过程返回一个或多个结果集。
本节描述下列主题:
用于存储过程的语法包括 FUNCTION 语句、CALL 语句以及可选的 REPORT 块。
%FUNCTION (DTW_SQL) function_name ([IN datatype arg1, INOUT datatype arg2, OUT resultsetname, ...]) { CALL stored_procedure [(resultsetname, ...)] [%REPORT [(resultsetname)] { %}] ... [%REPORT [(resultsetname)] { %}] [%MESSAGE %}] %}
其中:
BIGINT | DOUBLEPRECISION | SMALLINT |
CHAR | FLOAT | TIME |
CLOB1 | INTEGER | TIMESTAMP |
DATE | GRAPHIC | VARCHAR |
DECIMAL | LONGVARCHAR | VARGRAPHIC |
DOUBLE | LONGVARGRAPHIC |
|
1 CLOB 只能用作 OUT 和 INOUT 参数,并且 Net.Data 会解释大小(以字节计)。例如,如果将变量指定为 OUT CLOB(20000),则将把大小为 20K 的 CLOB 用作输出参数。 |
BIGINT | LONG |
CHAR | LONG RAW |
DATE | NUMBER |
DECIMAL | RAW |
FLOAT | VARCHAR / VACHAR2 |
INTEGER |
|
要点: | 当 Windows 或 Unix 上的 Net.Data 调用位于 OS/390 和 OS/400 上的 DB2 中的存储过程时,当从 DB2 数据库中检索 DECIMAL 数据时,这些操作系统上的存储过程必须使用主变量类型 DOUBLE 或 FLOAT。使用主变量类型 DOUBLE 或 FLOAT 将确保所返回的数据采用可读格式。 |
%FUNCTION (DTW_SQL) function_name()
%FUNCTION (DTW_SQL) function_name (IN datatype arg1, INOUT datatype arg2, OUT resultsetname...)
CALL stored_procedure
%REPORT [(resultsetname)] { ... %}
示例:
%FUNCTION (DTW_SQL) mystoredproc (IN CHAR(30) arg1) { CALL myproc %REPORT (mytable){ ... %ROW { ... %} ... %} %}
CALL stored_procedure[ (resultsetname1[, resultsetname2, ...]) ]
%REPORT[(resultsetname1)] { ... %}
示例:
%FUNCTION (DTW_SQL) mystoredproc (IN CHAR(30) arg1, OUT table1) { CALL myproc (table1, table2) %REPORT(table2) { ... %ROW { ... %} ... %} %}
示例:
%FUNCTION (DTW_ORA) orastp (IN datatype arg1, OUT datatype arg2,...) returns (DTWORA_RESULT) { CALL stored_oracle_function %}
可以将参数传送给存储过程,并且可以使存储过程更新参数值,以便将新值传送回 Net.Data 宏。函数参数列表上的参数数目和类型必须与为存储过程定义的数目和类型相匹配。例如,如果在参数列表上为存储过程定义的参数是 INOUT,则函数参数列表上相应的参数必须是 INOUT。如果在列表上为存储过程定义的参数的类型为 CHAR(30),则函数参数列表上相应的参数也必须是 CHAR(30)。
示例 1: 将参数值传送给存储过程
%FUNCTION (DTW_SQL) mystoredproc (IN CHAR(30) valuein) { CALL myproc ...
示例 2: 从存储过程中返回值
%FUNCTION (DTW_SQL) mystoredproc (OUT VARCHAR(9) retvalue) { CALL myproc ...
使用 SQL 或 ODBC 语言环境可以从存储过程中返回一个或多个结果集。可以将结果集存储在 Net.Data 表中,以便在宏中进一步处理或者使用 REPORT 块来处理。如果存储过程生成了多个结果集,则必须将名称与存储过程生成的每个结果集相关联。这是通过在 CALL 语句上指定参数来实现的。于是,您为结果集指定的名称可以与 REPORT 块或 Net.Data 表相关联,并允许您确定如何由 Net.Data 来处理每个结果集。您可以:
有关使用多个报告块时的指南和限制,参见多个 REPORT 块的准则和限制。
要返回单个结果集并使用缺省报告:
使用以下语法:
%FUNCTION (DTW_SQL) function_name () { CALL stored_procedure %}
例如:
%FUNCTION (DTW_SQL) mystoredproc() { CALL myproc %}
要返回单个结果集并指定 REPORT 块:
使用以下语法:
%FUNCTION (DTW_SQL) function_name () { CALL stored_procedure [(resultsetname)] %REPORT [(resultsetname)] { ... %} %}示例 1:
%FUNCTION (DTW_SQL) mystoredproc () { CALL myproc %REPORT { ... %ROW { ... %} ... %} %}
示例 2:
%FUNCTION (DTW_SQL) mystoredproc () { CALL myproc (mytable1) %REPORT (mytable1) { ... %ROW { ... %} ... %} %}
要将单个结果集存储在 Net.Data 表中以进行进一步处理:
使用以下语法:
%FUNCTION (DTW_SQL) function_name (OUT tablename) { CALL stored_procedure [(resultsetname)] %}
例如:
%DEFINE DTW_DEFAULT_REPORT = "NO" %FUNCTION (DTW_SQL) mystoredproc (OUT mytable1) { CALL myproc %}
注意,DTW_DEFAULT_REPORT 被设置为否,以便不为结果集生成缺省报告。
要返回多个结果集并使用缺省报告格式化来显示它们:
使用以下语法:
%FUNCTION (DTW_SQL) function_name () { CALL stored_procedure [(resultsetname1, resultsetname2, ...)] %}
此处未指定报告块。
例如:
%DEFINE DTW_DEFAULT_REPORT = "YES" %FUNCTION (DTW_SQL) mystoredproc () { CALL myproc %}
要返回多个结果集,并将结果集存储在 Net.Data 表中以便进行进一步处理:
使用以下语法:
%FUNCTION (DTW_SQL) function_name (OUT (resultsetname1, resultsetname2, ...) { CALL stored_procedure (resultsetname1, resultsetname2, ...) %}
例如:
%DEFINE DTW_DEFAULT_REPORT = "NO" %FUNCTION (DTW_SQL) mystoredproc (OUT mytable1, mytable2) { CALL myproc (mytable1, mytable2) %}
注意,DTW_DEFAULT_REPORT 被设置为否,以便不为结果集生成缺省报告。
要返回多个结果集并为显示处理指定 REPORT 块:
每个结果集都与它的一个或多个 REPORT 块相关联。使用以下语法:
%FUNCTION (DTW_SQL) function_name (, ...) { CALL stored_procedure (resultsetname1, resultsetname2, ...) %REPORT (resultsetname1) ... %ROW { ... %} ... %} %REPORT (resultsetname2) ... %ROW { ... %} ... %} ... %}
例如:
%FUNCTION (DTW_SQL) mystoredproc () { CALL myproc (mytable1, mytable2) %REPORT(mytable1) { ... %ROW { ... %} ... %} %REPORT(mytable2) { ... %ROW { ... %} ... %} %}
要返回多个结果集并为每个结果集指定不同的显示或处理选项:
可以为使用唯一的参数名的每个结果集指定不同的处理选项。示例 1:
%FUNCTION (DTW_SQL) mystoredproc (OUT mytable2) { CALL myproc (mytable1, mytable2, mytable3) %REPORT(mytable1) { ... %ROW { ... %} ... %} %}结果集 mytable1 是由相应的 REPORT 块来处理的,并且是由宏的编写者指定时才显示。结果集 mytable2 被存储在 Net.Data 表 mytable2 中,并且现在可用于进一步的处理,例如,传送给另一个函数。结果集 mytable3 是使用 Net.Data 的缺省报告格式来显示的,因为没有为它指定 REPORT 块。
示例 2:
%FUNCTION(DTW_SQL) mystoredproc(OUT mytable4, OUT mytable3) { CALL myproc (mytable1, mytable2, mytable3, mytable4) %REPORT(mytable2) { ... %ROW { ... %} ... %} %REPORT(mytable1) { ... %ROW { ... %} ... %} %REPORT(mytable4) { ... %ROW { ... %} ... %} %}
结果集 mytable2、mytable1 和 mytable4 是由它们的相应 REPORT 块按照这种次序来处理的,并且根据指定来显示。结果集 mytable4 和 mytable3 被存储在表变量中,以便进行进一步处理。在处理完三个 REPORT 块之后,结果集 mytable3 也将使用 Net.Data 的缺省报告格式在显示。
DataLink 是一种基本构造块,用于扩展可以存储在数据库文件中的数据类型。通过使用 DataLink, 存储在列中的实际数据便只是一个指向文件的指针了。这个文件可以是任何类型的文件;图象文件、语音记录或文本文件。DataLink 存储 URL 以便分辨文件的位置。
DATALINK 数据类型需要使用 DataLink 文件管理器。有关 DataLink 文件管理器的详情, 参见针对您的操作系统的 DataLink 文档。使用 DATALINK 数据类型之前,必须确保 Web 服务器对 DB2 文件管理器服务器所管理的文件系统具有访问权。
当 SQL 查询使用 DataLink 返回结果集时,将用具有 READ PERMISSION DB DataLink 选项的 FILE LINK CONTROL 创建 DataLink 列,DataLink 列中的文件路径包含一个访问令牌。DB2 使用访问令牌来授予对文件的访问权。没有这个访问令牌,所有对该文件的访问都将因权限违例而失败。当然, 访问令牌中可能包含要返回给浏览器的 URL 中不能使用的字符,例如分号字符 (;)。例如:
/datalink/pics/UN1B;0YPVKGG346KEBE;baibien.jpg
URL 无效,因为它包含分号 (;) 字符。要使该 URL 有效,必须使用 Net.Data 内置函数 DTW_URLESCSEQ 对该分号进行编码。当然,有些字符串处理必须在使用此函数之前执行,因为这个函数也将对斜线 (/) 进行编码。
可以编写一个 Net.Data MACRO_FUNCTION 来自动进行字符串处理并使用 DTW_URLESCSEQ 函数。在每个从 DATALINK 数据类型列中检索数据的宏中使用此技术。
示例 1:一个使 DB2 UDB 返回的 URL 自动编码的 MACRO_FUNCTION
%{ TO DO: Apply DTW_URLESCSEQ to a DATALINK URL to make it a valid URL. IN: DATALINK URL from DB2 File Manager column. RETURN: The URL with token portion is URL encoded %} %MACRO_FUNCTION encodeDataLink(in DLURL) { @DTW_rCONCAT( @DTW_rDELSTR( DLURL, @DTW_rADD(@DTW_rLASTPOS("/", DLURL), "1" ) ), @DTW_rURLESCSEQ( @DTW_rSUBSTR(DLURL, @DTW_rADD( @DTW_rLASTPOS("/", DLURL), "1" ) ) ) ) %}
在使用此 MACRO_FUNCTION 之后,URL 即被正确编码,DATALINK 列中指定的文件就可以在 任何 Web 浏览器上引用。
示例 2:一个 Net.Data 宏,指定返回 DATALINK URL 的 SQL 查询
%FUNCTION(DTW_SQL)myQuery(){ select name, DLURLCOMPLETE(picture) from myTable where name like '%river%' %REPORT{ %ROW{ <p> $(V1) <br /> Before Encoding: $(V2) <br /> After Encoding: @encodeDataLInk($(V2)) <br /> Make HREF: <a href="@encodeDataLink($(V2))"> click here </a> <br /> <p> %} %} %}
请注意,这里使用了 DataLink “文件管理器”函数。函数 dlurlcomplete 返回一个完整的 URL。
以下示例显示如何从宏调用关系数据库语言环境:
以下示例为 ODBC 语言环境定义和调用多个函数。
%DEFINE{ DATABASE="qesq1" SHOWSQL="YES" table="int_null" LOGIN="netdata1" PASSWORD="ibmdb2"%} %function(dtw_odbc) sq1() { create table int_null (int1 int, int2 int) %} %function(dtw_odbc) sql2() { insert into $(table) (int1) values (111) %} %function(dtw_odbc) sql3() { insert into $(table) (int2) values (222) %} %function(dtw_odbc) sql4() { select * from $(table) %} %function(dtw_odbc) sql5() { drop table $(table) %} %HTML(REPORT){ @sql1() @sql2() @sql3() @sql4() %}
%DEFINE{ LOGIN="ulogin" PASSWORD="upassword" DATABASE="" table= "utable" %} %FUNCTION(DTW_ORA) myQuery(){ select ename,job,empno,hiredate,sal,deptno from $(table) order by ename %} %MESSAGE{ 100 : "<b>WARNING</b>: No employee were found that met your search criteria.<p>" : continue %} %HTML(REPORT){ @myQuery() %}
以下示例显示了具有 DTW_SQL 函数定义的宏(该函数定义调用一个 SQL 存储过程)。 它有三个不同 数据类型的参数。DTW_SQL 语言环境根据参数的数据类型将每个参数传递给存储过程。当存储过程完成处理之后, 将返回输出参数,Net.Data 也将相应地更新变量。
%{*********************************************************** DEFINE BLOCK ************************************************************%} %DEFINE{ MACRO_NAME = "TEST ALL TYPES" DTW_HTML_TABLE = "YES" parm1 = "1" %{SMALLINT %} parm2 = "11" %{INT %} parm3 = "1.1" %{DECIMAL (2,1) %} %} %FUNCTION(DTW_SQL) myProc (INOUT SMALLINT parm1, INOUT INT parm2, INOUT DECIMAL(2,1) parm3){ CALL TESTTYPE %} %HTML (report){ <head> <title>Net.Data : SQL Stored Procedure: Example '$(MACRO_NAME)'. </title> </head> <body bgcolor="#bbffff" text="#000000" link="#000000"> <p> Calling the function to create the stored procedure. <p></p> @CRTPROC() <hr/> <h2> Values of the INOUT parameters prior to calling the stored procedure: </h2> <b>parm1 (SMALLINT)<p></b> $(parm1)<br /> <b>parm2 (INT)</b> $(parm2)<br /> <b>parm3 (DECIMAL)</b> $(parm3) <hr/> <h2> Calling the function that executes the stored procedure. </h2> <p> @myProc(parm1,parm2,parm3) </p><hr/> <h2> Values of the INOUT parameters after calling the stored procedure:<p> </h2> <p><b>parm1 (SMALLINT)</b><br /> $(parm1)<br /> <b>parm2 (INT)</b> $(parm2)<br /> <b>parm3 (DECIMAL)</b> $(parm3) </p></body> %}