Як визначити, чи зберігається процедура вже існує


130

Я повинен написати сценарій розгортання, який буде працювати, якщо збережена процедура існує чи не існує. тобто якщо воно існує, то мені потрібно його змінити, інакше створити.

Як я можу це зробити в sql.

Я використовую SQL Server 2005


Відповіді:


160

Якщо ви скасуєте та створили процедуру, ви втратите налаштування безпеки. Це може дратувати вашу DBA або повністю порушити вашу заявку.

Що я роблю, це створити тривіальну збережену процедуру, якщо вона ще не існує. Після цього ви можете ЗМІНИТИ збережену процедуру на свій смак.

IF object_id('YourSp') IS NULL
    EXEC ('create procedure dbo.YourSp as select 1')
GO
ALTER PROCEDURE dbo.YourSp
AS
...

Таким чином, налаштування безпеки, коментарі та інші мета деталі переживатимуть розгортання.


2
Принаймні, якщо ви скасуєте це, ви знаєте, що вам доведеться знову додати дозволи. Якщо ви керували цим sql, ви б не знали, чи має парост правильні дозволи чи ні, як ви не знали, створили його чи змінили.
Liazy

@Liazy просте рішення - додати код у, if object_id('YourSp') is null BEGIN ... ENDщоб додати належні дозволи після створення збереженої процедури.
салюс

4
думаю, інша відповідь трохи більш повна, оскільки вона лише тягне ідентифікатор об'єкта для збережених процедур. не звичайно мати однакову назву для різних типів, але це може статися
трубайт

149

Найчистіший спосіб - перевірити його існування, скинути його, якщо він існує, а потім відтворити його. Ви не можете вставити оператор "create proc" всередині оператора IF. Це має бути чудово:

IF OBJECT_ID('MySproc', 'P') IS NOT NULL
DROP PROC MySproc
GO

CREATE PROC MySproc
AS
BEGIN
    ...
END

1
Це буде працювати, але це видаляє будь-які зміни безпеки, застосовані до збереженої процедури.
Андомар

18
Зміни безпеки також повинні бути частиною сценаріїв. Таким чином, він буде належним чином задокументований. Це правильний підхід.
Ендер Віггін

@EnderWiggin За винятком випадків, коли впровадження безпеки не знає на час розробки ... Що робити, якщо розробник не знає, яким користувачам потрібно виконувати права?
Адріан Давел

2
@AdriaanDavel l Для цього потрібні DBA, а отримання DBA для розмови з розробниками називається управлінням. Якщо розробники та DBA не можуть працювати разом, у компанії є проблема. Крім того, належним чином реалізовані системи не покладаються на привілей користувача на торкання бази даних, саме для цього потрібні облікові записи служб, а безпека рівня обслуговування повинна застосовуватися на базі даних. Таким чином, DBA не повинні витрачати час і гроші на налаштування безпеки. окремі відростки.
Шон Вілсон

2
У мене не було б, щоб розробники скидали / відтворювали відростки, що належали комерційному продукту. Подумайте про це, я б також не мав цього робити. Я бачу, на що ви стикаєтесь, тобто "що робити, якщо DBA потрібно налаштувати безпеку на проміжному розгортанні для комерційного продукту". Я ще раз зазначу, що належним чином реалізовані системи не покладаються на користувацькі привілеї, і що безпека рівня обслуговування повинна застосовуватися на базі даних. Я працював з DBA, які встановлюватимуться в демо / подряпинну систему, а потім робити схему порівняння, щоб забезпечити безпечне оновлення, IMO - це те, що вони найняли.
Шон Вілсон

31

Якщо ви маєте справу лише зі збереженими процедурами, найпростіше зробити це, ймовірно, скинути прок, а потім відтворити його. Ви можете згенерувати весь код для цього за допомогою майстра згенерування сценаріїв на 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...

20

Від SQL Server 2016 CTP3вас можна використовувати новий DIE заяву замість великогоIF обгорток

Синтаксис:

ДРОП {PROC | ПРОЦЕДУРА} [ЯКЩО Є) {[схема_назва. ] процедура} [, ... n]

Запит:

DROP PROCEDURE IF EXISTS usp_name

Більше інформації тут


11
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

де xxxназва проц


4

На додаток до вже сказаного, я також хочу додати інший підхід і виступаю за використання стратегії диференційного розгортання сценарію. Замість того, щоб створити скрипт, який завжди перевіряє поточний стан і діє на основі цього стану, розгорніть за допомогою ряду сценаріїв без стану, які оновлюються до відомих версій . Я використовував цю стратегію, і вона окупається великим часом, оскільки мої сценарії розгортання тепер "АБО" безкоштовні.


Цікаво! За п'ять років, відколи ви опублікували цю відповідь, чи були подальші розробки методів контролю версій вашої бази даних?
Thomas L Holaday

4

Ви можете написати запит наступним чином:

IF OBJECT_ID('ProcedureName','P') IS NOT NULL
    DROP PROC ProcedureName
GO

CREATE PROCEDURE [dbo].[ProcedureName]
...your query here....

Щоб бути більш конкретним щодо вищевказаного синтаксису:
OBJECT_ID - це унікальний ідентифікаційний номер об'єкта в базі даних, він використовується внутрішньо SQL сервером. Оскільки ми передаємо ProcedureName, за яким ви об'єкту типу P, який повідомляє SQL Server, що ви повинні знайти об'єкт під назвою ProcedureName, який є типом процедури, тобто P

Цей запит знайде процедуру, і якщо вона буде доступна, вона видалить її та створить нову.

Для отримання детальної інформації про OBJECT_ID та типи об'єктів, відвідайте: SYS.Objects



0

У мене є збережений додаток, який дозволяє клієнту продовжувати перевірку, якщо він існує, я не хочу його змінювати, якщо він не - я не хочу його створювати, найкращий спосіб, який я знайшов:

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

2
Я не подав голосування, яке було прихильне, але, напевно, я б сказав, що це було знято з голосу, оскільки це рішення вводить нові ускладнення з уникненнями символів цитати в тілі збереженої процедури.
donperk

0

Код нижче перевіряє, чи зберігається процедура вже існує чи ні.

Якщо він існує, він зміниться, якщо його не існує, він створить для вас нову збережену процедуру:

//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 

0

Кращим варіантом може бути використання такого інструменту, як Red-Gate SQL Compare або SQL Examiner для автоматичного порівняння відмінностей та генерування сценарію міграції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.