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


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.