Stored-Procedures
為列設置值的儲存過程必須接受函式的返回值
我在 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 下面的建議是一個可以接受的解決方案。但是我添加了一個預設值
FALSE
to@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
文本時,您會看到引號已從傳入的函式中刪除。您可能需要嘗試不同的場景,但這是我解決原始問題的第一個想法。