113

Tôi phải viết một kịch bản triển khai sẽ hoạt động nếu một thủ tục được lưu trữ tồn tại hoặc không tồn tại. tức là nếu nó tồn tại, thì tôi cần phải thay đổi nó, nếu không thì tạo nó.

Làm thế nào tôi có thể làm điều này trong sql.

Tôi đang sử dụng SQL Server 2005

|
149

Nếu bạn DROP và TẠO quy trình, bạn sẽ mất các cài đặt bảo mật. Điều này có thể gây khó chịu cho DBA của bạn hoặc phá vỡ ứng dụng của bạn hoàn toàn.

Những gì tôi làm là tạo ra một thủ tục lưu trữ tầm thường nếu nó chưa tồn tại. Sau đó, bạn có thể THAY ĐỔI thủ tục được lưu trữ theo ý thích của bạn.

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

Bằng cách này, cài đặt bảo mật, nhận xét và meta Deta khác sẽ tồn tại khi triển khai.

|
  • 1

    Ít nhất nếu bạn thả nó, bạn biết bạn phải thêm lại các quyền. Nếu bạn chạy sql này, bạn sẽ không biết liệu sproc có quyền chính xác hay không vì bạn sẽ không biết liệu bạn đã tạo ra nó hay thay đổi nó.

    – Hoàng Gia Thịnh 12:03:55 25/01/2013
  • 1

    @Liazy giải pháp đơn giản là thêm mã vào if object_id('YourSp') is null BEGIN ... ENDđể thêm quyền thích hợp sau khi tạo thủ tục được lưu trữ.

    – Ngô Xuân Nhi 17:29:32 24/07/2013
  • 1

    nghĩ rằng câu trả lời khác hoàn chỉnh hơn một chút vì nó chỉ kéo id đối tượng cho các thủ tục được lưu trữ. không phổ biến để có cùng tên cho các loại khác nhau nhưng điều đó có thể xảy ra

    – Lê Từ Dung 14:08:00 25/08/2014
138

Cách sạch nhất là kiểm tra sự tồn tại của nó, thả nó nếu nó tồn tại và sau đó tạo lại nó. Bạn không thể nhúng câu lệnh "tạo Proc" bên trong câu lệnh IF. Điều này nên làm độc đáo:

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

CREATE PROC MySproc
AS
BEGIN
    ...
END
|
  • 1

    Điều này sẽ hoạt động, nhưng nó loại bỏ bất kỳ thay đổi bảo mật được áp dụng cho thủ tục được lưu trữ.

    – Vũ Phi Phượng 06:42:15 02/06/2009
  • 1

    Thay đổi bảo mật cũng là một phần của tập lệnh. Bằng cách đó, nó sẽ được ghi lại đúng cách. Đây là cách tiếp cận đúng.

    – Phan Ðắc Di 16:16:59 20/01/2012
  • 1

    @EnderWiggin Ngoại trừ nếu không biết triển khai bảo mật tại thời điểm thiết kế ... Điều gì xảy ra nếu nhà phát triển không biết người dùng nào cần quyền thực thi?

    – Phan Hữu Ðạt 05:54:21 22/11/2013
  • 1

    @AdriaanDavel l đó là những gì DBA dành cho và để các DBA nói chuyện với các nhà phát triển được gọi là quản lý. Nếu các nhà phát triển và DBA không thể làm việc cùng nhau thì có vấn đề với công ty. Ngoài ra, các hệ thống được triển khai đúng cách không dựa vào đặc quyền của người dùng để chạm vào cơ sở dữ liệu, đó là tài khoản dịch vụ dành cho và bảo mật cấp dịch vụ nên được áp dụng trên toàn cơ sở dữ liệu, theo cách này, các DBA không phải mất thời gian và tiền bạc để điều chỉnh bảo mật sprocs cá nhân.

    – Hoàng Thái San 06:52:39 06/12/2013
  • 1

    Tôi sẽ không có nhà phát triển bỏ / tái tạo các sprocs thuộc về một sản phẩm thương mại. Hãy suy nghĩ về điều đó, tôi cũng sẽ không có các DBA làm điều đó. Tuy nhiên, tôi thấy những gì bạn đang nhận được, tức là "điều gì sẽ xảy ra nếu các DBA cần phải điều chỉnh bảo mật trên một triển khai hậu kỳ cho một sản phẩm thương mại". Tôi sẽ nhắc lại rằng các hệ thống được triển khai đúng cách không dựa vào đặc quyền của người dùng và bảo mật cấp dịch vụ nên được áp dụng trên toàn cơ sở dữ liệu. Tôi đã làm việc với các DBA sẽ cài đặt hệ thống demo / cào và sau đó thực hiện so sánh lược đồ để đảm bảo nâng cấp an toàn, IMO đây là việc họ được thuê để làm.

    – Tạ Giáng Uyên 20:24:56 16/12/2013
30

Nếu bạn chỉ xử lý các thủ tục được lưu trữ, điều dễ nhất để làm là có thể bỏ Proc, sau đó tạo lại nó. Bạn có thể tạo tất cả các mã để thực hiện việc này bằng trình hướng dẫn Tạo tập lệnh trong 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...
|
14

Từ SQL Server 2016 CTP3bạn có thể sử dụng các câu lệnh DIE mới thay vì các IFhàm bao lớn

Cú pháp:

DROP {PROC | THỦ TỤC} [NẾU EXISTS] {[lược đồ tên. ] thủ tục} [, ... n]

Truy vấn:

DROP PROCEDURE IF EXISTS usp_name

Thêm thông tin ở đây

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

nơi xxxlà tên proc

|
3

Ngoài những gì đã được nói, tôi cũng muốn thêm một cách tiếp cận khác và ủng hộ việc sử dụng chiến lược triển khai tập lệnh khác biệt. Thay vì tạo một tập lệnh trạng thái luôn kiểm tra trạng thái hiện tại và hành động dựa trên trạng thái đó, hãy triển khai thông qua một loạt các tập lệnh không trạng thái nâng cấp từ các phiên bản nổi tiếng . Tôi đã sử dụng chiến lược này và nó mang lại kết quả lớn vì các kịch bản triển khai của tôi giờ đây hoàn toàn miễn phí 'NẾU'.

|
  • 1

    Hấp dẫn! Trong năm năm kể từ khi bạn đăng câu trả lời này, sau đó có những phát triển hơn nữa trong phương pháp kiểm soát phiên bản cơ sở dữ liệu của bạn không?

    – Trịnh Thúy Huyền 20:11:30 05/08/2014
2
IF OBJECT_ID('SPNAME') IS NULL
     -- Does Not Exists
ELSE
     -- Exists
|
0

Bạn có thể viết một truy vấn như sau:

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

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

Để cụ thể hơn về cú pháp trên:
OBJECT_ID là số id duy nhất cho một đối tượng trong cơ sở dữ liệu, điều này được SQL Server sử dụng nội bộ. Vì chúng tôi đang truyền cho RoutureName, theo sau là loại đối tượng P , thông báo cho SQL Server rằng bạn sẽ tìm thấy đối tượng có tên là RoutureName , thuộc loại thủ tục, tức là

Truy vấn này sẽ tìm thủ tục và nếu có sẵn, nó sẽ bỏ nó và tạo một thủ tục mới.

Để biết thông tin chi tiết về các loại OBRI_ID và Object, vui lòng truy cập: SYS.Objects

|
0

Tùy chọn tốt hơn có thể là sử dụng một công cụ như So sánh SQL cổng đỏ hoặc Trình kiểm tra SQL để tự động so sánh sự khác biệt và tạo tập lệnh di chuyển.

|
0

Mã dưới đây sẽ kiểm tra xem thủ tục được lưu trữ đã tồn tại hay chưa.

Nếu nó tồn tại, nó sẽ thay đổi, nếu nó không tồn tại, nó sẽ tạo ra một thủ tục lưu trữ mới cho bạn:

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

Tôi có một Proc được lưu trữ cho phép khách hàng mở rộng xác nhận, nếu nó tồn tại tôi không muốn thay đổi nó, nếu tôi không muốn tạo nó, cách tốt nhất tôi đã tìm thấy:

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
|
  • 1

    Tôi đã không cung cấp phiếu bầu xuống, nhưng, theo phỏng đoán, tôi sẽ nói rằng nó đã bị bỏ phiếu vì giải pháp này đưa ra các biến chứng mới với việc thoát các ký tự trích dẫn trong phần thân của thủ tục được lưu trữ.

    – Trịnh Thúy Huyền 16:02:07 08/07/2016

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.