Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
而带有游标和动态SQL的循环不会终止_Sql_Sap Ase - Fatal编程技术网

而带有游标和动态SQL的循环不会终止

而带有游标和动态SQL的循环不会终止,sql,sap-ase,Sql,Sap Ase,我喜欢编写一个过程,返回每个表的名称,该表有一个具有特定id的行。换句话说,这些表有一个列“id”,该列的类型为varchar,包含一个uuid。在做了一些研究之后,我选择了以下简化方法,重点关注我无法解决/理解的问题: -- get a cursor for all foo table names that have an id column DECLARE table_name_cursor CURSOR FOR SELECT a.name FROM sysobjects a, syscol

我喜欢编写一个过程,返回每个表的名称,该表有一个具有特定id的行。换句话说,这些表有一个列“id”,该列的类型为varchar,包含一个uuid。在做了一些研究之后,我选择了以下简化方法,重点关注我无法解决/理解的问题:

-- get a cursor for all foo table names that have an id column
DECLARE table_name_cursor CURSOR FOR
SELECT a.name
FROM sysobjects a, syscolumns b 
WHERE a.id = b.id 
    AND a.name like 'Foo%'
    AND b.name = 'id'

GO

-- define some variables
DECLARE @current_table_name VARCHAR(100)
DECLARE @id_found VARCHAR(100)

OPEN table_name_cursor
FETCH table_name_cursor INTO @current_table_name
WHILE @@SQLSTATUS = 0
BEGIN
    EXEC ('SELECT @id_found = id from ' + @current_table_name + " where id = '@id_param'") -- @id_param will be passed with the procedure call
    select @current_table_name  
    FETCH table_name_cursor INTO @current_table_name
END

-- clean up resources
CLOSE table_name_cursor
DEALLOCATE table_name_cursor
它的工作原理与预期一样,当游标的大小相当小时(在我的例子中为20个表),但如果游标的大小增加,则过程永远不会终止

这听起来像是一个资源问题,但我在Sybase Fu的白色腰带无助于找到答案

问:为什么它停止使用“太多”光标行,有没有办法让它使用这种方法


有没有其他更好的方法来解决在所有表上运行查询的实际问题?这不是用于生产,它只是某种开发/维护脚本。

在注释周围添加上下文可能会有所帮助,因为注释停止工作,例如,proc是否意外返回,proc是否生成堆栈跟踪,它是否真的“停止”或“运行时间比预期长”

一些基本的监控应该有助于了解发生了什么:

显示游标进程的sp_是否被其他进程阻止(例如,对您查询的数据具有独占锁定) 定期查询master..monProcessWaits,其中SPID=显示任何等待时间较长的事件,例如,磁盘读取的等待时间较长;网络写入等待时间长 SPID=show cpu/wait/logicalreads/physicalreads的master..{monProcessStatement | monProcessObject}的定期查询是否显示cpu/wait/logicalreads/physicalreads在增加? 我猜您的一些选择是针对id列上没有可用索引的大型表运行的,最终结果是一些选择运行昂贵且缓慢的表和/或索引扫描,可能需要等待从磁盘中提取大量数据

如果我的猜测是正确的,MDA表应该显示磁盘等待、逻辑/物理读取以及较小程度的cpu的数量不断增加

此外,如果您看到大量逻辑/物理读取指示表/索引扫描,则当前运行的SELECT的查询计划应确认使用了表/索引扫描,因此无法在当前表的id列上查找/使用索引

对于较小/较快的测试运行,我猜您正在访问较小的表(表/索引扫描相对较快)和/或在id列上具有可用索引的b表(因此索引查找相对较快)

有些别的事情要考虑…您使用什么应用程序进行proc调用

我已经记不清用户遇到某些。。。我应该说“时髦”问题吗。。。访问ASE时;该问题通常可追溯到前端/客户端应用程序的配置或编码问题

在这些情况下,我建议用户通过isql命令行工具运行查询和/或过程,看看是否得到相同的“funky”结果;isql命令行会话通常不显示“funky”行为,因此指出了用户用于访问ASE的任何应用程序/工具的问题

注意:isql命令行工具的意思就是。。。命令行工具。。。不要与wisql或dbisql或任何其他点击式GUI工具混淆,其中许多工具在某些场景下确实会导致一些“时髦”行为


注意:即使这是一个客户端问题而不是ASE问题,MDA表通常可以指出这一点,例如,monProcessWaits在等待输出到客户端完成时可能会显示大量的等待时间;在此场景中,sp_还将显示spid状态为send sleep ie,ASE正在等待客户端处理ASE发送给客户端的最后一个结果集。

感谢您的全面回答!!然后这个过程永远不会终止-希望这样解释:/它根本不会终止,我必须断开与数据库的连接才能停止它,没有消息,没有错误,没有部分结果,什么都没有。就像:有20个表,它在几毫秒内终止,有21个,它运行>1分钟,可能永远不知道它是否正好是20-如果该值很重要,我可以尝试一些测试来获得确切的边界,但是“永不终止”是指几分钟后它没有完成,还是6小时后它没有完成,或者2天后它没有完成?对于较大的表、较小的数据缓存、相对较慢的磁盘。。。对一张桌子进行扫描可能需要10分钟到几个小时。。。将其乘以多个大表扫描。。。你的评论“永不终止”太模糊了。。。您确实需要监视MDA表以查看发生了什么,例如,执行一些大型表扫描需要很长时间
她的头发很小。10..500行。没什么大不了的。似乎有一个最大游标大小,它在几毫秒内返回一个结果,如果超过该大小,我必须终止连接才能终止。Sybase ASE对游标处理的行数没有任何限制。如果你想弄清楚问题出在哪里,那么你必须卷起袖子,开始做一些挖掘工作,例如MDA表格。