缺少开始和结束?

时间:2012-02-28 21:06:41

标签: sql-server

我很确定发生了什么,但是想从我的SQL Server Travellers那里得到一些想法(实际上很明显发生了什么,但我认为这是一个有趣的讨论)。

谜这个蝙蝠侠......这是怎么回事?

CREATE PROCEDURE ToBeDropped
AS
BEGIN
PRINT 'Drop me!';
END
DROP PROCEDURE ToBeDropped;

会发生什么?我的第一个想法是创建过程然后立即删除。 Wrongo!除非你之前已经知道过这个问题,否则你可能会想到同样的事情......承认它!

在SSMS中按Ctrl-T将查询结果切换为文本。然后运行以下命令(或者您可以编写新程序ToBeDropped脚本):

SELECT m.[definition]
FROM sys.sql_modules AS m INNER JOIN sys.objects AS obj
ON m.object_id = obj.object_id
WHERE obj.name = 'ToBeDropped';

接下来运行程序:

EXECUTE ToBeDropped;

重新运行上述sys.sql_modules查询或尝试编写脚本脚本。你不能,因为它不再存在。

嗯......这里发生了什么事?显然,while程序有一个隐含的BEGIN和END,类似于以下内容:

CREATE PROCEDURE ToBeDropped
AS
BEGIN
BEGIN
PRINT 'Drop me!';
END
DROP PROCEDURE ToBeDropped;
END;

当格​​式化得更好时,如下所示:

CREATE PROCEDURE ToBeDropped
AS
BEGIN
    BEGIN
        PRINT 'Drop me!';
    END

    DROP PROCEDURE ToBeDropped;
END ;

我不是隐性行为的忠实粉丝。我更喜欢明确。 TSQL正朝着变得更“真实”的方向发展 - 请参阅现在可用或可能在TSQL中使用的分号和所有CLR功能。我想看到一个CREATE PROCEDURE主体需要至少有1个BEGIN和END对 - heck make {是BEGIN的别名/同义词}和END的别名/同义词 - 我们将更接近TSQL转向进入C#。

思考?意见?谢谢!

2 个答案:

答案 0 :(得分:2)

drop procedure是proc的一部分,在调用proc

之前,proc不会被删除

这将创建并删除proc,注意GO这是批处理终止符,如果你没有drop语句将成为proc本身的一部分

CREATE PROCEDURE ToBeDropped
AS
BEGIN
PRINT 'Drop me!';
END
GO
DROP PROCEDURE ToBeDropped;

当你这样做时

CREATE PROCEDURE ToBeDropped
AS
BEGIN
PRINT 'Drop me!';
END
DROP PROCEDURE ToBeDropped;

proc已创建,但在调用proc

之前不会被删除
EXEC  ToBeDropped

这与BEGIN无关,但因为DROP PROC是程序本身的一部分,直到你调用它才会被执行

当你尝试再次执行proc时

EXEC  ToBeDropped

您收到以下消息

Msg 2812, Level 16, State 62, Line 1
Could not find stored procedure 'ToBeDropped'.

答案 1 :(得分:0)

这是一个相当开放的问题,很可能因模糊而被关闭。也许你可以重新询问Meta Overflow?

然而,在关闭之前,据我所知,推理不是因为BEGIN和END。这是因为GO。创建过程将所有逻辑放在其下,直到它到达文件末尾或GO。所以,这是您正在寻找的显性值:

CREATE PROCEDURE ToBeDropped
AS
BEGIN
    PRINT 'Drop me!';
END
--Completes the procedure creation
GO
DROP PROCEDURE ToBeDropped;