触发器中的sybase游标

时间:2012-02-15 14:41:17

标签: triggers cursor sybase-ase

我正在尝试在Solaris上运行的sybase ASE 15.0.3系统的触发器中使用游标。这样做的目的是我想知道表的哪一列正在更新。然后,我将此信息保存在管理表中以供进一步查找。

create trigger test_trigger on my_table for update as

set nocount on

/* declare cursor */
declare @colname varchar(64)

declare column_name cursor for 
    select syscolumns.name from syscolumns join sysobjects on (sysobjects.id = syscolumns.id) where sysobjects.name = 'my_table'

/* open the cursor */
open column_name

/* fetch the first row */
fetch column_name into @colname

/* now loop, processing all the rows
** @@sqlstatus = 0 means successful fetch
** @@sqlstatus = 1 means error on previous fetch
** @@sqlstatus = 2 means end of result set reached
*/
while (@@sqlstatus != 2)
begin    
    /* check for errors */
    if (@@sqlstatus = 1)
    begin
        print "Error in column_names cursor"
        return
    end

    /* now do the insert if colum was updaed  */
    if update(@colname)
    begin
        insert into my_save_table (login,tablename,field,action,pstamp) 
            select suser_name(),'my_table',@colname,'U',getdate() from inserted
    end

    /* fetch the next row */
    fetch column_name into @colname
end

/* close the cursor and return */
close column_name   
go

不幸的是,当尝试在isql中运行它时,我收到以下错误:

 Msg 102, Level 15, State 1:
 Server 'my_sybase_server', Procedure 'test_trigger', Line 34:
 Incorrect syntax near '@colname'.

我做了一些调查,发现第34行意味着以下声明:

if update(@colname)

然后我试着检查1列并用

替换它
if update(some_column_name)

这实际上工作正常,我没有任何其他想法如何解决这个问题。看起来update()函数不知何故不允许包含变量。我没有找到有关sybase书籍或谷歌等任何其他地方的任何其他信息。有没有人可以为此找到解决方案?它可能是一个错误吗?是否有光标的变通方法?

感谢您的任何建议

2 个答案:

答案 0 :(得分:0)

问题是update(@colname)类似update('colname'),需要update(colname)。为了实现这一目标,您需要使用动态SQL

我已经看过the documentation并且可以使用:

  

动态执行Transact-SQL

     

当与string或char_variable选项一起使用时,执行连接提供的字符串和变量来执行   生成Transact-SQL命令。这种形式的执行命令可以   用于SQL批处理,过程和触发器。


检查this article以获取有关如何使用动态sql的示例!

答案 1 :(得分:0)

如果每次更改表(添加/删除列)时重新创建触发器都不是问题,您可以使用此类查询生成触发器的主体

select 
'if update('+c.name+')
   set @colname = '''+c.name+'''
'
from syscolumns c where id = object_id('my_table')