Создавайте объекты SSDT (хранимые процедуры и т. Д. c.), Только если выполняется условие - PullRequest
0 голосов
/ 13 июля 2020

Я переделываю существующую базу данных для работы с SSDT для контроля версий и упрощения развертывания после того, как что-то изменилось. Для этого мне нужно создать хранимые процедуры, которые создаются только тогда, когда другая база данных не существует на локальном компьютере. Затем эти процедуры будут получать свои данные со связанного сервера sql, а не с локального (виртуальные машины / среды тестирования имеют свою собственную базу данных и не нуждаются в этих процедурах с использованием связанной базы данных / сервера).

Проблема с SSDT: Когда вы добавляете хранимую процедуру в свой проект базы данных в Visual Studio, вы не можете использовать условия (или инструкции t- sql в целом?).

Есть ли другое решение этой проблемы, кроме установки для действия сборки сценария значения «none» и ссылки на него в сценарии после развертывания, где я могу использовать условия? Я почти уверен, что объекты после развертывания не будут отображаться при использовании инструмента сравнения схем, который было бы неплохо иметь.

Нет ничего необычного в процедурах или временных таблицах в целом, основная проблема заключается в их создании только в том случае, если специфическая c база данных не существует на локальном компьютере.

Пример хранимой процедуры: (старый скрипт, который я сейчас переделываю для SSDT) ( XTSQL01 - связанный сервер в данном случае)

SET ANSI_NULLS ON;
USE [BI]
GO
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
/* =================================================================================
  Author: [ - ] 
  Create date: [ 2019-09-17 ] 
  Description: [ procedure to fetch Stock Data from linked Steps to BI
==================================================================================== */

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[BI].[DS].[FETCH_STOCK_LINKED]') AND type in (N'P', N'PC'))
  DROP PROCEDURE [DS].[FETCH_STOCK_LINKED]
GO

CREATE PROCEDURE [DS].[FETCH_STOCK_LINKED]
AS 
BEGIN 

    SET NOCOUNT ON;
    DECLARE @errNumber INT, @errSeverity INT, @errState INT, @errProc VARCHAR(500), @errLine INT, @errMsg VARCHAR(500);

    BEGIN TRY

        DELETE FROM [BI].[DS].[STOCK];

    END TRY  
    BEGIN CATCH
        SET @errNumber = ERROR_NUMBER();
        SET @errSeverity = ERROR_SEVERITY();
        SET @errState = ERROR_STATE();
        SET @errProc = ERROR_PROCEDURE();
        SET @errLine = ERROR_LINE();
        SET @errMsg = ERROR_MESSAGE();
        
        INSERT INTO [BI].[DS].[ERRORDATA] (ERR_NUMBER, ERR_SEVERITY, ERR_STATE, ERR_PROCEDURE, ERR_LINE, ERR_MESSAGE, ERR_DATE)
        VALUES (@errNumber, @errSeverity, @errState, @errProc, @errLine, @errMsg, GETDATE());

    END CATCH

    BEGIN TRY

        INSERT INTO [BI].[DS].[STOCK] (ARTICLENUMBER, STOCKAMOUNT, STOCKVALUE, STOCKROOM)
        SELECT SUB.ARTICLENUMBER as ARTICLENUMBER, SUB.STOCKAMOUNT as STOCKAMOUNT, SUB.STOCKVALUE as STOCKVALUE, SUB.STOCKROOM as STOCKROOM
        FROM
        (
            SELECT I.S_ITEMNO as ARTICLENUMBER, SUM(SQ.N_ITEMQUANTITY) as STOCKAMOUNT, SUM(SQ.N_ITEMQUANTITY*I.N_AVGPURCHASE) as STOCKVALUE, SR.S_ABBREVIATION as STOCKROOM
            FROM [XTSQL01].[Steps].[sao].[STOCKQUANT] SQ WITH (NOLOCK)
            INNER JOIN [XTSQL01].[Steps].[sao].[STOCKROOM_M] SR WITH (NOLOCK) ON SQ.I_STOCKROOM_M = SR.I_STOCKROOM_M
            LEFT JOIN [XTSQL01].[Steps].[sao].[ITEM_M] I WITH (NOLOCK) ON SQ.I_ITEM_M = I.I_ITEM_M
            WHERE SQ.DT_DELETED IS NULL 
            --AND SQ.I_STOCKROOM_M = 1
            GROUP BY I.S_ITEMNO, SR.S_ABBREVIATION
        ) SUB
        WHERE SUB.STOCKAMOUNT > 0

    END TRY  
    BEGIN CATCH
        SET @errNumber = ERROR_NUMBER();
        SET @errSeverity = ERROR_SEVERITY();
        SET @errState = ERROR_STATE();
        SET @errProc = ERROR_PROCEDURE();
        SET @errLine = ERROR_LINE();
        SET @errMsg = ERROR_MESSAGE();
        
        INSERT INTO [BI].[DS].[ERRORDATA] (ERR_NUMBER, ERR_SEVERITY, ERR_STATE, ERR_PROCEDURE, ERR_LINE, ERR_MESSAGE, ERR_DATE)
        VALUES (@errNumber, @errSeverity, @errState, @errProc, @errLine, @errMsg, GETDATE());

    END CATCH   

END
GO

Пример временной таблицы:

CREATE TABLE [BI].[DS].[ORDERDATA_TEMP_DELETE]
(
    ORDERNUMBER decimal(28,0) NOT NULL
);
GO

1 Ответ

0 голосов
/ 14 июля 2020

Для этих процедур необходимо создать отдельный проект. Итак, предположим, что ваш текущий проект называется ProjectA. Вам нужно создать другой проект, скажем, ProjectA_ext, и добавить в него ссылку на базу данных для ProjectA с параметром The same database. В этом случае ProjectA_ext будет иметь все объекты из ProjectA в дополнение ко всем объектам из ProjectA_ext.

Еще одно соображение: я не уверен, что вам нужно именно это. Если у вас есть проблемы со связанным сервером, вам необходимо создать синонимы для всех внешних объектов (имена 3 и 4 части) и использовать переменные для внешних баз данных и / или связанных серверов.

...