Devo scrivere uno script di distribuzione che funzionerà se esiste una procedura memorizzata o non esiste. cioè se esiste, allora devo modificarlo, altrimenti crearlo.
Come posso fare questo nel sql.
Sto usando SQL Server 2005
Devo scrivere uno script di distribuzione che funzionerà se esiste una procedura memorizzata o non esiste. cioè se esiste, allora devo modificarlo, altrimenti crearlo.
Come posso fare questo nel sql.
Sto usando SQL Server 2005
Risposte:
Se DROP e CREATE la procedura, perderete le impostazioni di sicurezza. Ciò potrebbe infastidire il tuo DBA o interrompere completamente la tua applicazione.
Quello che faccio è creare una banale stored procedure se non esiste ancora. Successivamente, è possibile modificare la procedura memorizzata a proprio piacimento.
IF object_id('YourSp') IS NULL
EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...
In questo modo, le impostazioni di sicurezza, i commenti e altri meta-deta sopravviveranno alla distribuzione.
if object_id('YourSp') is null BEGIN ... END
per aggiungere le autorizzazioni appropriate dopo aver creato la procedura memorizzata.
Il modo più pulito è testarne l'esistenza, rilasciarlo se esiste e quindi ricrearlo. Non è possibile incorporare un'istruzione "create proc" in un'istruzione IF. Questo dovrebbe fare bene:
IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO
CREATE PROC MySproc
AS
BEGIN
...
END
Se hai a che fare solo con stored procedure, la cosa più semplice da fare è probabilmente abbandonare il proc, quindi ricrearlo. È possibile generare tutto il codice per farlo utilizzando la procedura guidata Genera script in SQL Server.
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourSproc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[YourSproc]
CREATE PROCEDURE YourSproc...
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xxx]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
CREATE PROCEDURE dbo.xxx
dov'è xxx
il nome proc
Oltre a quanto è già stato detto, mi piace anche aggiungere un approccio diverso e sostenere l'uso della strategia di distribuzione degli script differenziali. Invece di creare uno script con stato che controlli sempre lo stato corrente e agisca in base a quello stato, distribuire tramite una serie di script senza stato che si aggiornano da versioni ben note . Ho usato questa strategia e ripaga alla grande in quanto i miei script di distribuzione sono ora tutti 'IF' gratuiti.
È possibile scrivere una query come segue:
IF OBJECT_ID('ProcedureName','P') IS NOT NULL
DROP PROC ProcedureName
GO
CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....
Per essere più specifici sulla sintassi sopra:
OBJECT_ID è un numero ID univoco per un oggetto all'interno del database, utilizzato internamente da SQL Server. Dato che stiamo passando ProcedureName seguito dal tuo tipo di oggetto P che dice a SQL Server che dovresti trovare l'oggetto chiamato ProcedureName che è di tipo procedure, cioè P
Questa query troverà la procedura e, se disponibile, la rilascerà e ne creerà una nuova.
Per informazioni dettagliate su OBJECT_ID e sui tipi di oggetto, visitare: SYS.Objects
IF OBJECT_ID('SPNAME') IS NULL
-- Does Not Exists
ELSE
-- Exists
Ho un proc memorizzato che consente al cliente di estendere la validazione, se esiste non voglio cambiarlo, se non lo voglio creare, il modo migliore che ho trovato:
IF OBJECT_ID('ValidateRequestPost') IS NULL
BEGIN
EXEC ('CREATE PROCEDURE ValidateRequestPost
@RequestNo VARCHAR(30),
@ErrorStates VARCHAR(255) OUTPUT
AS
BEGIN
SELECT @ErrorStates = @ErrorStates
END')
END
Il codice seguente controlla se la procedura memorizzata esiste già o meno.
Se esiste, cambierà, se non esiste creerà una nuova procedura memorizzata per te:
//syntax for Create and Alter Proc
DECLARE @Create NVARCHAR(200) = 'Create PROCEDURE sp_cp_test';
DECLARE @Alter NVARCHAR(200) ='Alter PROCEDURE sp_cp_test';
//Actual Procedure
DECLARE @Proc NVARCHAR(200)= ' AS BEGIN select ''sh'' END';
//Checking For Sp
IF EXISTS (SELECT *
FROM sysobjects
WHERE id = Object_id('[dbo].[sp_cp_test]')
AND Objectproperty(id, 'IsProcedure') = 1
AND xtype = 'p'
AND NAME = 'sp_cp_test')
BEGIN
SET @Proc=@Alter + @Proc
EXEC (@proc)
END
ELSE
BEGIN
SET @Proc=@Create + @Proc
EXEC (@proc)
END
go