触发器中的 sybase 游标

发布于 2025-01-05 16:18:36 字数 1740 浏览 5 评论 0原文

我正在尝试在 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)

That 实际上工作得很好,但我不这样做不知道如何解决这个问题。看起来 update() 函数不知何故不允许包含变量。我没有在 sybase 书籍或 google 等其他地方找到任何其他信息。有人可以找到解决方案吗?这可能是一个错误吗?是否有针对光标的解决方法?

感谢您的任何建议

I am trying to use a cursor in a trigger on a sybase ASE 15.0.3 system running on Solaris. The purpose for this is that I want to know which column of a table is getting updated. This information I then save in an admin table for further lookups.

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

Unfortunately when trying to run this in isql I get the following error:

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

I did some investigations and found out that line 34 means the following statement:

if update(@colname)

then I tried to just check on 1 column and replaced it by

if update(some_column_name)

That actually worked fine and I don't have any other idea how to fix that. It looks like the update() function somehow not allows to contain a variable. I did not find any additional information on the sybase books or anywhere else in google ect. Does anybody may find a solution for this? Is it may a bug? Are there workarounds for the cursor?

Thanks for any advice

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼中杀气 2025-01-12 16:18:36

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

我已经看到 文档并且可以使用:

动态执行 Transact-SQL

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


查看这篇文章了解如何使用动态sql的示例!

The problem is that update(@colname) is something like update('colname') and needs to be update(colname). In order to you achieve that, you need to use Dynamic SQL.

I've already saw the documentation and it's possible to use:

Dynamically executing Transact-SQL

When used with the string or char_variable options, execute concatenates the supplied strings and variables to execute the
resulting Transact-SQL command. This form of the execute command may
be used in SQL batches, procedures, and triggers.


Check this article for an example on how to use dynamic sql!

ぃ双果 2025-01-12 16:18:36

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

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

If it is not a problem to recreate the trigger every time the table is altered (columns added/dropped) you may just generate the body for your trigger with such query

select 
'if update('+c.name+')
   set @colname = '''+c.name+'''
'
from syscolumns c where id = object_id('my_table')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文