让我们假设我们有一个SQL服务器重新启动时自动运行简单的日志记录步骤:如果我们试图用参数过程中,我们会得到错误相同SQL服务器 - sp_procoption标记与参数
USE master
GO
CREATE TABLE dbo.silly_logging(id INT IDENTITY(1,1) PRIMARY KEY
,created_date DATETIME DEFAULT GETDATE()
,comment VARCHAR(100));
GO
-- no parametrs
CREATE PROCEDURE dbo.my_procedure
AS
INSERT INTO dbo.silly_logging(comment)
VALUES ('SQL Server Startup');
GO
-- mark procedure to start at SQL Server instance startup
EXEC sp_procoption @ProcName = 'dbo.my_procedure'
, @OptionName = 'startup'
, @OptionValue = 'on';
SELECT name, is_auto_executed
FROM master.sys.procedures
WHERE is_auto_executed = 1;
-- my_procedure 1
-- restart instance
SELECT *
FROM dbo.silly_logging;
--id created_date comment
--1 2017-07-28 07:01:24.650 SQL Server Startup
:
CREATE PROCEDURE dbo.my_procedure2 @i INT = 10
AS
SELECT @i;
GO
-- mark procedure to start at SQL Server instance startup
EXEC sp_procoption @ProcName = 'dbo.my_procedure2'
, @OptionName = 'startup'
, @OptionValue = 'on';
Msg 15399, Level 11, State 1, Procedure sp_procoption,
Could not change startup option because this option is restricted to objects that have no parameters.
但是我们仍然能ALTER
现行程序:
ALTER PROCEDURE dbo.my_procedure @text NVARCHAR(100) = 'Default value'
AS
INSERT INTO dbo.silly_logging(comment)
VALUES (@text);
GO
-- restart instance
SELECT *
FROM dbo.silly_logging;
--id created_date comment
--1 2017-07-28 07:01:24.650 SQL Server Startup
--2 2017-07-28 07:03:50.510 Default value
现在我们结束存储过程,并提供参数(默认值)。
缺点:无法关闭。
EXEC sp_procoption @ProcName = 'dbo.my_procedure'
, @OptionName = 'startup'
, @OptionValue = 'off';
Msg 15399, Level 11, State 1, Procedure sp_procoption Could not change startup option because this option is restricted to objects that have no parameters.
当然,如果我用预期DROP-CREATE
一切都将正常工作。
- DROP PROCEDURE - 对象被删除,
ExecAtStartup
性过 - CREATE PROCEDURE使用默认参数删除
- EXEC sp_procoption - 将返回错误
- 程序不会被解雇
但用CREATE-ALTER
的路径是:
- CREATE PROCEDURE不带参数
- EXEC sp_procoption(程序将开始启动)
- ALTER PROCEDURE使用默认参数
- 程序将被解雇
有什么具体原因这项工作呀?具体而言,为什么在修改对象属性(如ExecAtStartup
)未验证时?
因为设计师没有预料到像你这样的邪恶人士?你在寻找什么样的答案?你为什么不直接从一个包装程序中调用你的过程,该过程足够坚持“无参数”规则? –
@JeroenMostert我搜索了一些关于验证元数据的注释(MSDN,BOL)。这仅仅是一个例子。像查看'WITH SCHEMABINDING'基础对象不能改变。这个问题更多的是关于内部。 – lad2025
对我来说,作为一名程序员,很明显'sp_procoption'是后来为标记启动而添加的一个新功能,它可以验证您以这种方式标记的过程(无论是“开”还是“关”)。 'ALTER'是引擎的核心命令,不知道或不关心这个程序是否在启动时使用,并且会很高兴地让你在脚下自拍。这仅仅是来自不同层面的机制的紧急行为;如果有人撰写关于此行为的官方文档,我会非常惊讶。 (可能是无聊MVP的博客文章。) –