在TOAD DB2中编写匿名块时出错

时间:2015-03-26 04:45:06

标签: isolation-level db2-luw

我是DB2的新手。我想在蟾蜍中执行一个匿名的黑色。

BEGIN ATOMIC
DECLARE TEMP_SCHEMA VARCHAR(12) ;
SET TEMP_SCHEMA = 'SCHEMA1';
SELECT * FROM TEMP_SCHEMA.TABLE_NAME
WHERE 1=1 
WITH UR;
END;

我收到以下错误: 20159:[IBM] [DB2 / AIX64] SQL20159W由于语句上下文,忽略了隔离子句。

你能帮忙吗?

1 个答案:

答案 0 :(得分:1)

根据https://www.ibm.com/support/knowledgecenter/en/SSMKHH_10.0.0/com.ibm.etools.mft.doc/ak04940_.htm?view=embed的文档,"如果指定了ATOMIC,则只允许一个消息流实例(即一个线程)执行特定BEGIN ATOMIC的语句。 .END语句(由其架构和标签标识),任何时候。如果不存在标签,则行为就像指定了零长度标签一样。 当需要对共享变量进行大量更改时,BEGIN ATOMIC构造非常有用,并且防止其他实例看到数据的中间状态非常重要。"

在存储过程中使用ATOMIC意味着您的代码将作为单例执行,从而提供最大隔离。这将与你的"与UR"直接冲突。隔离选项。即使您在脚本中而不是在存储过程中使用ATOMIC关键字,DB2仍然将其视为单个线程,因此如果您包含尝试降低隔离级别的查询提示,它将会抱怨。

删除ATOMIC关键字后,您将收到令牌错误,因为您的SELECT * FROM TEMP_SCHEMA.TABLE_NAME WHERE 1 = 1语句试图从BEGIN块内部将结果集返回Toad。不幸的是,这在DB2中是不可能的。只要有任何强制使用BEGIN块的过程代码,DB2就会坚决拒绝将数据返回给客户端。我发现从BEGIN块内部返回结果的唯一方法是将BEGIN块放在存储过程中,然后使用CURSOR将结果集返回到Toad,例如

BEGIN

DECLARE C1 CURSOR with RETURN WITH HOLD FOR SELECT * FROM .EMPLOYEE;   OPEN C1;

END;

请注意,必须将CURSOR代码包含在内部BEGIN块中,DB2在将结果集发送回客户端WITH HOLD时需要该块。

如果要从原型存储过程中将变量的值返回Toad,可以使用以下方法:

BEGIN

DECLARE C1 CURSOR WITH RETURN WITH HOLD FOR 
SELECT * FROM TABLE(SELECT * FROM (VALUES(<variable goes here>)) 
AS TEMP(<descriptive name for the variable goes here>)) AS TEMP1;
OPEN C1;

END;

总而言之,为了在Toad等开发工具中使用匿名块作为原型工具,如果要返回任何结果,必须将其包装在存储过程中,并且必须使用嵌入的CURSOR这样做的内部BEGIN块。遗憾的是,在这方面,DB2比MS SQL Server更加繁琐。