Stored-Procedures

為列設置值的儲存過程必須接受函式的返回值

  • January 14, 2020

我在 Data Mart 中創建了一個非常簡單的表來儲存 ETL 診斷資訊:

CREATE TABLE [internal].[etl_status]
(
   [property_name] VARCHAR(100) NOT NULL PRIMARY KEY, 
   [property_value] VARCHAR(MAX) NULL
)

然後我創建了一個儲存過程來處理對該表的插入/修改。除了方便之外,我還必須這樣做,因為 Microsoft 尚未將 T-SQL 語句活動添加到 Azure 數據工廠。

問題是,我不知道如何讓儲存過程接受 T-SQL 函式作為參數。事實上,我相信這可能是不可能的。所以這是我的小解決方法:

CREATE PROCEDURE [internal].[sp_set_etl_status]
   @propertyName VARCHAR(100)
  ,@propertyValue VARCHAR(MAX)
AS

DECLARE @query AS VARCHAR(MAX)

-- Case statement to handle functions passed as propertyValue parameter
-- NOT IDEAL, see solution by Scott Hodgin below
SET @propertyValue = CASE @propertyValue
   WHEN 'GETDATE()' THEN CONVERT(VARCHAR(MAX),CONVERT(DATETIME2(2), GETUTCDATE()))
   ELSE @propertyValue
   END

SET @query = '
BEGIN
   IF NOT EXISTS ( SELECT * FROM [internal].[etl_status]
                       WHERE [property_name] =''' + @propertyName + ''')
   BEGIN
       INSERT INTO [internal].[etl_status]
       VALUES (''' + @propertyName + ''',  NULL)
   END
END

UPDATE [internal].[etl_status]
SET [property_value] = ''' + @propertyValue+ '''
WHERE [property_name] = ''' + @propertyName + '''
;'

EXEC(@query)

這按預期工作。但是對於目前的解決方案,我需要為我想要處理的每個函式都有一個 CASE 語句。

編輯: Scott Hodgin 下面的建議是一個可以接受的解決方案。但是我添加了一個預設值FALSEto@propertyValueIsFunction如下@propertyValueIsFunction BIT = FALSE

如果可以向您的儲存過程 ( PropertyValueIsFunction bit) 添加一個附加參數,您可以測試該條件並用於REPLACE去除引號。這是一個例子:

CREATE PROCEDURE [dbo].[sp_set_etl_status]
   @propertyName VARCHAR(100)
  ,@propertyValue VARCHAR(MAX)
  ,@propertyValueIsFunction bit
AS

DECLARE @query AS VARCHAR(MAX)

SET @query = '
BEGIN
   IF NOT EXISTS ( SELECT * FROM [internal].[etl_status]
                       WHERE [property_name] =''' + @propertyName + ''')
   BEGIN
       INSERT INTO [internal].[etl_status]
       VALUES (''' + @propertyName + ''',  NULL)
   END
END

UPDATE [internal].[etl_status]
SET [property_value] = ''' + @propertyValue+ '''
WHERE [property_name] = ''' + @propertyName + '''
;'
if @propertyValueIsFunction = 1
   set @query = replace(@query,'''' + @propertyValue + '''',@propertyValue) 
print @Query
--EXEC(@query)

假設(注意額外的參數值 1 表示函式):

exec [dbo].[sp_set_etl_status] 'admission_last_import_start_dttm', 'GETDATE()',1

生成的查詢結果如下所示:

BEGIN
   IF NOT EXISTS ( SELECT * FROM [internal].[etl_status]
                       WHERE [property_name] ='admission_last_import_start_dttm')
   BEGIN
       INSERT INTO [internal].[etl_status]
       VALUES ('admission_last_import_start_dttm',  NULL)
   END
END

UPDATE [internal].[etl_status]
SET [property_value] = GETDATE()
WHERE [property_name] = 'admission_last_import_start_dttm'
;

當您列印@query文本時,您會看到引號已從傳入的函式中刪除。

您可能需要嘗試不同的場景,但這是我解決原始問題的第一個想法。

引用自:https://dba.stackexchange.com/questions/257262