Sybase 15.X中提供了内置的存储过程sp_recompile。该存储过程可令表中的存储过程和触发器在下次使用时重新编译。(Causes each stored procedure and trigger that uses the named table to be recompiled the next time it runs.)
存储过程和触发器使用的查询,仅在编译时优化一次。当systabstats统计信息,如行数或聚簇率(cluster ratio)发生显著改变时,已编译的存储过程和触发器效率可能会变低,并可能会受益于sp_recompile的重新编译。通过对表的存储过程和触发器进行重新编译,可优化查询以获得最佳效率。
在Sybase ASE 15.X中,create index和update statistics会自动重新编译存储过程和触发器。在这些情况下使用sp_recompile会导致冗余的重新编译。
该存储过程的唯一输入变量,是数据表的对象名称。
Sybase官方手册给出的语法示例为:
Recompiles each trigger and stored procedure that uses the tabletitlesthe next time the trigger or stored procedure is run:
sp_recompile titles
但实际使用中(ASE 15.7),却总是得到如下错误提示:
Msg 17460
Object must be in the current database.
如果在表名前加上用户名,如user_name.title,则会得到如下错误提示:
Msg 102
Incorrect syntax near '.'.
全网查询了一下,用这个存储过程的人很少啊……
百思不得其解,于是使用sybsystemprocs..sp_helptext sp_recompile查看该存储过程的源代码。
create procedure sp_recompile@objnamevarchar(767)asdeclare @typesmallintdeclare @uidintdeclare @msg varchar(1024)declare @dbname varchar(255)if @objname like '%%.%%.%%' andsubstring(@objname, 1, charindex(".", @objname) - 1) != db_name()begin/*** 17390, "Table or view name must be in 'current' database."*/raiserror 17390return (1)endif not exists (select *from sysobjectswhere id = object_id(@objname))begin/*** 17460, "Object must be in the current database."*/raiserror 17460return (1)end
唯一的输入变量@objname是varchar()类型。如果是使用dbname.username.tabname方法写的,还会检查输入的dbname与当前数据库(db_name())是否一致。然后直接将@objname送入sysobjects表中查询对应的id。
这就很容易理解了:需要为输入加上单引号,如:
sp_recompile 'username.tablename'
或
sp_recompile 'dbname.username.tablename'