【问题标题】:Sybase ASE: how to print all table rows using cursor?Sybase ASE:如何使用游标打印所有表行?
【发布时间】:2020-05-17 01:16:59
【问题描述】:

以下代码应该打印临时表#table_A中包含的所有行:

create table #table_A
    (
     ID                  int          NULL ,
     foo                 int          NULL 
    )

go

insert into #table_A values (1, 2)
insert into #table_A values (2, 3)
go

declare c_table_A cursor                     
    for select *                                    
          from #table_A                      
         order                                      
            by 1                                                                      

open c_table_A                               
  fetch c_table_A                            
  while @@sqlstatus = 0                             
    begin                                           
      print '%1!', c_table_A                 
      fetch c_table_A                        
    end                                             
close c_table_A   


go  

但是,它会导致以下错误消息:

DECLARE CURSOR must be the only statement in a query batch.  

如何打印(临时)表中包含的所有行?


这是我提出问题的另一种方式:

我正在尝试做类似的事情:

open c_table_A                               
  fetch c_table_A into @record_variable                           
  while @@sqlstatus = 0                             
    begin                                           
      print '%1!', @record_variable
      fetch c_table_A into @record_variable                       
    end                                             
close c_table_A   

有没有办法在sybase中声明一个包含整行表的变量?


P.S.:仅使用“select * from ...”对我不起作用。在打印行之前,我需要对每一行做一些事情。 (我的问题应该集中在基本部分,这就是为什么我没有详细说明我需要对每一行做的其他事情)

【问题讨论】:

  • 在“open”之前单独放置一个“go”。
  • 一旦你添加了go(根据Richard的评论),你需要修复fetch命令,你需要将光标列获取到@variables,然后你需要将那些@variables 提供给print 命令;但是看看你如何(有效地)用一个简单的select * from ...(即,不需要游标、循环或print)完成同样的事情,我的主要问题是......你真正想要完成什么?
  • 我会做“从#table_A中选择*”(然后是go)。这里不需要光标。
  • 我知道我可以将列保存到变量中,然后打印变量......但在我的应用程序中,我正在处理一个由其他几个表组成的大型临时表。将每一列保存在一个变量中会很麻烦。因此,我想将整行保存到一个“行变量”中
  • @markp 查看我更新的帖子

标签: sql sap-ase cursors


【解决方案1】:

感谢您的澄清。

在 SQL 批处理而不是存储过程中,游标声明必须与使用它的批处理分开,因此在 declare cursor 和后续批处理之间需要有一个 go

抱歉,无法在 Sybase ASE 中定义“行变量”。返回到变量中的每一列都必须为它声明一个变量。在下面的示例中,@id 和 @foo 被声明为与表中的列 id 和 foo 相同的类型。其他 RDBMS 确实有“记录数据类型”,但遗憾的是 Sybase ASE 没有。

在决定使用游标之前,游标在大表上会相对较慢,您可以在 select 语句中执行其他处理。如果有条件逻辑case ... when ... then ... else ... end 可能会被证明是有用的,尽管直接从 select 语句中调用存储过程是不可能的,但您可以调用 SQL 用户定义函数。如果您需要帮助,这可能是一个单独的问题。

我还添加了deallocate cursor 语句,它是语法的一部分,可以释放与您的连接相关的内部工作空间。

您可能希望在运行批处理之前执行set nocount on,它会删除有时烦人的(1 row affected) 消息。


set nocount on
go

create table #table_A
    (
     ID                  int          NULL ,
     foo                 int          NULL 
    )
go

insert into #table_A values (1, 2)
insert into #table_A values (2, 3)
go

declare c_table_A cursor                     
    for select *                                    
          from #table_A                      
         order                                      
            by 1                                                                      
go

declare
    @id     int,
    @foo    int

open c_table_A                               
fetch c_table_A into @id, @foo

while @@sqlstatus = 0                             
begin                                           
    print 'id: %1! foo: %2!', @id, @foo
    fetch c_table_A into @id, @foo
end                                             

close c_table_A   
go 

deallocate cursor c_table_A
go

【讨论】:

  • 在 ASE 16 中 IS 有一种定义行(又名表)变量的方法:table variable,尽管访问表变量是通过普通表级命令完成的(例如,插入、更新、删除)
猜你喜欢
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多