返回首页

gbase数据、南大通用产品文档:GBase8s部件爆炸问题

更新日期:2024年09月11日

当您使用由程序逻辑补充的游标时,您可解决普通的 SQL 不可解决的问题。这些问题之
一就是部件爆炸问题,有时称为材料单处理。此问题的核心是对象之间的递归关系;一个
对象包含其他对象,其又包含其他对象。
通常以制造库存为例来说明该问题。例如,公司制造各种部件。有些部件是分立的,但有
些是其他部件的组合。
在可能称为 contains 的单个表中说明这些关系。列 contains.parent 持有系组合的部件的部件
编号。列 contains.child 具有为父部件的组件的部件的部件编号。如果部件编号 123400 是
九个部件的组合,则存在九行,123400 在第一列中,其他部件编号在第二列中。下图展示
描述部件编号 123400 的多行中的一行。
图: 部件爆炸问题


部件爆炸问题在于:给定一个部件编号,产生为那个部件的组件的所有部件的列表。下列
示例是一种解决方案的概要,如以 GBase 8s ESQL/C 实现的那样:
int part_list[200];

boom(top_part)
int top_part;
{
long this_part, child_part;
int next_to_do = 0, next_free = 1;

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 217 -

part_list[next_to_do] = top_part;

EXEC SQL DECLARE part_scan CURSOR FOR
SELECT child INTO child_part FROM contains
WHERE parent = this_part;
while(next_to_do < next_free)
{
this_part = part_list[next_to_do];
EXEC SQL OPEN part_scan;
while(SQLCODE == 0)
{
EXEC SQL FETCH part_scan;
if(SQLCODE == 0)
{
part_list[next_free] = child_part;
next_free += 1;
}
}
EXEC SQL CLOSE part_scan;
next_to_do += 1;
}
return (next_free - 1);
}
从技术上讲,contains 表的每一行都是有向无环图,或树,的头结点。该函数执行对该树的
宽度优先搜索,树根是作为它的参数传递的部件编号。该函数使用名为 part_scan 的游标返
回在 parent 列中带有特定的值的所有行。最内层的 while 循环打开 part_scan 游标,在选择
集中访存每一行,并当已检索了每一组件的部件编号时,关闭该游标。
此函数解决部件爆炸问题的核心,但该函数不是完整的解决方案。例如,它不允许组件在
树中出现多个级别。此外,实际的 contains 表还会有列count,给出在每一 parent 中使用
的 child 部件的计数。返回每一组件部件的总计数的程序要复杂得多。
之前描述的迭代方法不是解决部件爆炸问题的唯一方法。如果代的数目有固定的限制,则
您可使用嵌套的外部自连接,以单个 SELECT 语句解决该问题。
如果在一个最高级别部件内,可包含最多四代部件,则下列 SELECT 语句返回所有部件:

SELECT a.parent, a.child, b.child, c.child, d.child
FROM contains a
OUTER (contains b,

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 218 -

OUTER (contains c, outer contains d) )
WHERE a.parent = top_part_number
AND a.child = b.parent
AND b.child = c.parent
AND c.child = d.parent
此 SELECT 语句为来源于指定为 top_part_number 的祖先的每一行返回一行。对于不存在
的级别,返回 Null 值。
(请使用指示符变量来检测它们。)要将此解决方案扩展到更多级
别,请选择 contains 表的附加的嵌套外部连接。您还可修订此解决方案来返回每一级别上
部件的数目的计数。

Join 方式的Hint
功能描述
指明Join 使用的方法,可以为Nested Loop、Hash Join 和Merge Join。
语法格式
[no] nestloop|hashjoin|mergejoin(table_list)
参数说明

no 表示hint 的join 方式不使用。

table_list 为表示hint 表集合的字符串,该字符串中的表与join_table_list 相同,只是中
间不允许出现括号指定join 的优先级。
例如:
no nestloop(t1 t2 t3)表示:生成t1、t2、t3 三表连接计划时,不使用nestloop。三表连接
计划可能是t2 t3 先join,再跟t1 join,或t1 t2 先join,再跟t3 join。此hint 只hint 最后一次
join 的join 方式,对于两表连接的方法不hint。如果需要,可以单独指定,例如:任意表均
不允许nestloop 连接,且希望t2 t3 先join,则增加hint:no nestloop(t2 t3)。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
571
示例
对示例中原语句使用如下hint:
explain
select /*+ nestloop(store_sales store_returns item) */ i_product_name product_name ...
该hint 表示:生成store_sales、store_returns 和item 三表的结果集时,最后的两表关联
使用nestloop。生成计划如下所示:

当 GBase 8s 实例配置为 DRDA 应用程序服务器时, GBase 8s 提供支持分布式
关系数据库架构(DRDA)协议的内置函数。(这通过在配置文件中将
DBSERVERALIASES 设置为 DRDA 来实现。)

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1723

sysibm.Metadata 函数向驱动程序为 JDBC 和 SQL 客户端应用程序提供
数据库元数据信息。

sysibm.SCLCAMessage 函数支持 DRDA 错误处理。
这些函数的 GBase 8s 实现符合 DR Level 5 SQLAM 7 标准。
Metadata 函数
sysibm.Metadata 函数是一个 SPL 例程,它可由 GBase Data Server 驱动程序调
用,以便 JDBC 和 SQL 应用程序动态检索数据库元数据。Metadata 例程在配
置为 DRDA 应用程序服务器的 GBase 8s 实例的每个数据库中自动创建,客户端
应用程序必须指定 'sysibm' 为所有者名称以从符合 ANSI 的数据库调用此函数。
它具有以下常规定义:
create procedure sysibm.METADATA() returning
integer as allProceduresAreCallable,
integer as allTablesAreSelectable,
integer as nullsAreSortedHigh,
integer as nullsAreSortedLow,
integer as nullsAreSortedAtStart,
integer as nullsAreSortedAtEnd,
integer as usesLocalFiles,
integer as usesLocalFilePerTable,
integer as storesUpperCaseIdentifiers,
integer as storesLowerCaseIdentifiers,
integer as storesMixedCaseIdentifiers,
integer as storesLowerCaseQuotedIdentifiers,
integer as storesMixedCaseQuotedIdentifiers,
lvarchar(4096) as getSQLKeywords,
varchar(100) as getNumericFunctions,
varchar(100) as getStringFunctions,
varchar(100) as getSystemFunctions,
varchar(100) as getTimeDateFunctions,
varchar(25) as getSearchStringEscape,
varchar(25) as getExtraNameCharacters,
integer as supportsAlterTableWithAddColumn,
integer as supportsAlterTableWithDropColumn,

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1724
integer as supportsConvert,
varchar(255) as supportsConvertType,
integer as supportsDifferentTableCorrelationNames,
integer as supportsExpressionsInOrderBy,
integer as supportsOrderByUnrelated,
integer as supportsGroupBy,
integer as supportsGroupByUnrelated,
integer as supportsGroupByBeyondSelect,
integer as supportsMultipleResultSets,
integer as supportsMultipleTransactions,
integer as supportsCoreSQLGrammar,
integer as supportsExtendedSQLGrammar,
integer as supportsANSI92IntermediateSQL,
integer as supportsANSI92FullSQL,
integer as supportsIntegrityEnhancementFacility,
integer as supportsOuterJoins,
integer as supportsFullOuterJoins,
integer as supportsLimitedOuterJoins,
varchar(50) as getSchemaTerm,
varchar(50) as getProcedureTerm,
varchar(50) as getCatalogTerm,
integer as isCatalogAtStart,
varchar(50) as getCatalogSeparator,
integer as supportsSchemasInDataManipulation,
integer as supportsSchemasInProcedureCalls,
integer as supportsSchemasInTableDefinitions,
integer as supportsSchemasInIndexDefinitions,
integer as supportsSchemasInPrivilegeDefinitions,
integer as supportsCatalogsInDataManipulation,
integer as supportsCatalogsInProcedureCalls,
integer as supportsCatalogsInTableDefinitions,
integer as supportsCatalogsInIndexDefinitions,
integer as supportsCatalogsInPrivilegeDefinitions,
integer as supportsPositionedDelete,
integer as supportsPositionedUpdate,

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1725
integer as supportsSelectForUpdate,
integer as supportsStoredProcedures,
integer as supportsSubqueriesInComparisons,
integer as supportsUnion,
integer as supportsUnionAll,
integer as supportsOpenCursorsAcrossCommit,
integer as supportsOpenCursorsAcrossRollback,
integer as supportsOpenStatementsAcrossCommit,
integer as supportsOpenStatementsAcrossRollback,
integer as getMaxBinaryLiteralLength,
integer as getMaxCharLiteralLength,
integer as getMaxColumnNameLength,
integer as getMaxColumnsInGroupBy,
integer as getMaxColumnsInIndex,
integer as getMaxColumnsInOrderBy,
integer as getMaxColumnsInSelect,
integer as getMaxColumnsInTable,
integer as getMaxConnections,
integer as getMaxCursorNameLength,
integer as getMaxIndexLength,
integer as getMaxSchemaNameLength,
integer as getMaxProcedureNameLength,
integer as getMaxCatalogNameLength,
integer as getMaxRowSize,
integer as doesMaxRowSizeIncludeBlobs,
integer as getMaxStatementLength,
integer as getMaxStatements,
integer as getMaxTableNameLength,
integer as getMaxTablesInSelect,
integer as getMaxUserNameLength,
integer as getDefaultTransactionIsolation,
integer as supportsTransactions,
varchar(50) as supportsTransactionIsolationLevel,
integer as supportsDataDefinitionAndDataManipulationTransactions,
integer as supportsDataManipulationTransactionsOnly,

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1726
integer as dataDefinitionCausesTransactionCommit,
integer as dataDefinitionIgnoredInTransactions,
varchar(100) as supportsResultSetType,
varchar(100) as supportsResultSetConcurrency,
varchar(100) as ownUpdatesAreVisible,
varchar(100) as ownDeletesAreVisible,
varchar(100) as ownInsertsAreVisible,
varchar(100) as othersUpdatesAreVisible,
varchar(100) as othersDeletesAreVisible,
varchar(100) as othersInsertsAreVisible,
varchar(100) as updatesAreDetected,
varchar(100) as deletesAreDetected,
varchar(100) as insertsAreDetected,
integer as supportsBatchUpdates,
integer as supportsSavepoints,
integer as supportsGetGeneratedKeys
sysibm.SQLCAMessage 函数
缺省情况下,用于 JDBC 的 GBase Data Server Driver 和用于 GBase 8s 的 SQL
不返回本地化错误消息。但是当在连接 URL 中设置
"retrieveMessagesFromServerOnGetMessage=true" 属性时,需要来自
服务器的详细和本地化的错误消息。
SQLCAMessage 函数是一个 SPL 例程,支持从远程 DB2 或 GBase 8s 数据库
服务器到使用分布式关系数据库架构(DRDA)协议的客户端应用程序检索详细
的错误消息文本。在配置为 DRDA 应用程序服务器的 GBase 8s 实例的每个数据
库中自动创建 SQLCAMessage 例程。用于 JDBC 和 SQL 客户端应用程序
GBase Data Server 驱动程序必须指 'sysibm' 所有者名称,以从符合 ANSI 的数
据库调用此函数。
SQLCAMessage 函数基于 SQL 通信区域(SQLCA)中的 SQLSTATE 代码检
索本地化的错误消息。
此函数的定义使用 IN 、OUT 和 INOUT 参数:
CREATE function sysibm.SQLCAMessage (
IN SQLCode INTEGER,

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1727
IN SQLErrml SMALLINT,

IN SQLErrmc VARCHAR(70),
IN SQLErrp CHAR(8),
IN SQLErrd0 INTEGER,

IN SQLErrd1 INTEGER,

IN SQLErrd2 INTEGER,
IN SQLErrd3 INTEGER,
IN SQLErrd4 INTEGER,
IN SQLErrd5 INTEGER,
IN SQLWarn CHAR(11),


IN SQLState CHAR(5),


IN MessageFileName VARCHAR(20),
INOUT Locale VARCHAR(33),
OUT Message LVARCHAR(4096),
OUT Rcode INTEGER)
RETURNING INTEGER
EXTERNAL NAME '(SQLCAMessage)'
LANGUAGE C
要调用此函数,可以使用此语法:
sysibm.SQLCAMessage

参数
描述
限制
语法
error_number
错误的 SQLCODE 值
必须存在
表达式
input_locale
接收消息的输入语言环境的名
称。缺省为 U.S. English 语言
环境(en_us)
必须存在
标识符
message_file
消息文件的名称
必须存在
路径名
该函数从指定的 SQLCODE 和 input_locale 的指定 message_file 检索文本。返
回的代码表示调用执行 SQLCAMessage 例程成功或失败。
GBase 8s DRDA 应用程序试图使用指定的输出参数检索错误消息文本:

SQLCODE

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1728

input_locale 和

message_file
GBase 8s DRDA 应用程序试图使用指定的输出参数检索错误消息文本:如果
MessageFileName 参数 message_file 为 NULL ,则使用缺省的消息文件
(errmsgtxt)。如果使用指定的 input_locale 检索失败,则使用缺省语言环境
(en_us)来检索错误消息。如果适用,令牌数组用于替换检索的消息文本中的标
记。
如果检索成功,

SQLCODE 从错误消息中移除,

错误消息复制到 OUT 参数 'Message'

用于检索消息的区域设置将复制到 INOUT 参数 'Locale'。
如果检索失败,则错误消息文本 "Message not found" 将出现在 Message 参
数中。
对于这两种情况,OUT 参数 Rcod 设置为执行此 SPL 例程的返回码。
ISAM 错误的详细信息从 SQLERRD[0] 值提供。ISAM 错误消息连接到实际的
错误消息字符串并返回到应用程序。
对于 SQLCAMessage 函数可以返回相应错误消息文本的 SQLSTATE 值的代
码,请参阅 SQLSTATE 代码列表。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1729
7. 附录