SQL存储过程是否可以自行删除并继续执行?

时间:2014-05-29 15:29:59

标签: sql

具体来说,我可以这样做吗?

CREATE PROC AutoDestructiveStoredProcedure
AS
DROP PROC AutoDestructiveStoredProcedure
PRINT 'Still alive.'
GO

这是一种不好的做法吗?

预期的行为是什么?它是否根据实施而改变? 在SQL Server,MySQL和Oracle中执行此操作有什么区别?

5 个答案:

答案 0 :(得分:2)

是的,这将起作用 - 至少在SQL Server 2008 R2中。它继续执行直到程序结束,之后程序就消失了。

这是不好的做法吗?我认同。在我看来,主要原因是它将DDL与DML混合在一起,对通常易于理解的操作(调用存储过程)施加了意想不到的副作用。

不幸的是,我无法就MySQL或Oracle的工作方式回答你的问题。

答案 1 :(得分:1)

是的,你可以这样做,不知道你为什么要

CREATE PROC AutoDestructiveStoredProcedure
AS
PRINT 'Being killed'
DROP PROC AutoDestructiveStoredProcedure
PRINT 'Still alive.'
exec createAutoDestruct
print 'Alive Again'
GO

create proc createAutoDestruct as

Exec sp_executesql N'CREATE PROC AutoDestructiveStoredProcedure
AS
PRINT ''Being killed''
DROP PROC AutoDestructiveStoredProcedure
PRINT ''Still alive.''
exec createAutoDestruct
print ''Alive Again'' '
GO


AutoDestructiveStoredProcedure
AutoDestructiveStoredProcedure

答案 2 :(得分:1)

我在Oracle中收集了以下实验证据。我创建了以下过程:

create procedure selfdestruct is
begin
execute immediate 'drop procedure selfdestruct';
end selfdestruct;

然后,使用

运行它
exec selfdestruct;

结果似乎是一个永无止境的程序。简要了解数据库活动会发现会话正在等待library cache pin,这似乎是Oracle用来阻止程序对象在使用中进行更改的方法。

简而言之,对于Oracle,答案是“不,你不能在程序运行时删除它。”

答案 3 :(得分:0)

您可以使用自毁来忘记客户群上的对象 这将适用于Microsoft SQL Server 2008 R2(SP2)和Oracle 11G(也可能是10g)

在Microsoft SQL Server 2008 R2(SP2)

CREATE PROC AutoDestructiveStoredProcedure
AS
PRINT 'Being killed'
DROP PROC AutoDestructiveStoredProcedure
PRINT 'Still alive.'
print 'Alive Again'
GO


select OBJECT_ID('AutoDestructiveStoredProcedure')

- 1243151474

exec AutoDestructiveStoredProcedure

- 被杀

- 还活着。

- 再次活着

select OBJECT_ID('AutoDestructiveStoredProcedure')

- 空

在oracle上

SET serveroutput ON size unlimited;

 CREATE OR REPLACE PROCEDURE selfdestruct
 AS
   v_plSqlBlock varchar2(500);
   v_job_int binary_integer;
     BEGIN
       DBMS_OUTPUT.PUT_LINE('Being killed');

     v_plSqlBlock  :=' 
     BEGIN
     execute immediate ''drop procedure selfdestruct'';
     END;
     ';

       dbms_job.submit(
                   job =>  v_job_int,
                   what => v_plSqlBlock
                   );     
     commit;
       DBMS_OUTPUT.PUT_LINE('Still alive.');
       DBMS_OUTPUT.PUT_LINE('Alive Again');
     END selfdestruct;
     /



 SELECT count(1)
 FROM dba_procedures
 WHERE object_name = upper('selfdestruct');

答案 4 :(得分:0)

原因很简单:我在一个不是管理员的数据库上工作,并且我不希望其他人查看和编辑我的SP,因此我在运行该程序之前以及最后在程序运行时创建它我必须删除它,以免将其保留在数据库中。