Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL存储过程是否可以删除自身并继续执行?_Sql - Fatal编程技术网

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

SQL存储过程是否可以删除自身并继续执行?,sql,Sql,具体来说,我可以这样做吗 CREATE PROC AutoDestructiveStoredProcedure AS DROP PROC AutoDestructiveStoredProcedure PRINT 'Still alive.' GO 这是个坏习惯吗 预期的行为是什么?它是否根据实施情况而改变? 在SQL Server、MySQL和Oracle中执行此操作有什么区别?是的,至少在SQL Server 2008 R2中可以。它继续执行,直到过程结束,然后过程结束 这是坏习惯吗?我认为

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

CREATE PROC AutoDestructiveStoredProcedure
AS
DROP PROC AutoDestructiveStoredProcedure
PRINT 'Still alive.'
GO
这是个坏习惯吗

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

是的,至少在SQL Server 2008 R2中可以。它继续执行,直到过程结束,然后过程结束

这是坏习惯吗?我认为是这样。在我看来,主要原因是它将DDL与DML混合在一起,给通常理解良好的操作(调用存储过程)带来了意想不到的副作用


不幸的是,我无法回答您关于它如何在MySQL或Oracle上工作的问题。

是的,您可以这样做,但不确定为什么要这样做

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

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

create procedure selfdestruct is
begin
execute immediate 'drop procedure selfdestruct';
end selfdestruct;
然后,使用

exec selfdestruct;
结果似乎是一个永无止境的过程。简要查看数据库活动可以发现会话正在等待
库缓存pin
,这似乎是Oracle用来防止过程对象在使用过程中发生更改的方法


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

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

在Microsoft SQL Server 2008 R2(SP2)上

--1243151474

exec AutoDestructiveStoredProcedure
--被杀

--还活着

--又活了

select OBJECT_ID('AutoDestructiveStoredProcedure')
--空的

论甲骨文

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');

原因很简单:我处理的数据库不是我的管理员,我不希望其他人看到和编辑我的SP,因此我在运行程序之前在运行时从程序中创建它,最后我必须删除它,以免将其留在数据库中。

哪个DBMS?SQLServer?神谕MySQL?你为什么要做这样的事情?这只是一个有趣的问题,我无法想象它会有什么用处。
这是一种不好的做法吗?
-当然,是的。这个过程将在5,4,3,2,1中自毁。猛敲这很有趣。我会深入挖掘,可能会问另一个疯狂的问题。谢谢你的答案并没有真正回答OP的问题。看见
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');