web-dev-qa-db-ja.com

Azure Data Warehouse-ユーザー定義関数の問題

Azureデータウェアハウス データベースでUDFを作成して使用することに、ここの誰もが運がよかったですか?オンプレミスのウェアハウスをSQL Server 2014からAzure datawarehouseに移行している最中に、UDFで問題が発生しました。

CREATE FUNCTION dbo.fn_GetImpliedRate (@Multiple float, @term int)
RETURNS float
AS
BEGIN
    DECLARE @ImpInt float
    IF(@Term = 1)
        SET @ImpInt = (select [1] from  dbo.ImpliedRate where Multiple = @Multiple); 
    IF(@Term = 2)
        SET @ImpInt = (select [2] from  dbo.ImpliedRate where Multiple = @Multiple); 
    IF(@Term = 3)
        SET @ImpInt = (select [3] from  dbo.ImpliedRate where Multiple = @Multiple); 
    IF(@Term = 4)
        SET @ImpInt = (select [4] from  dbo.ImpliedRate where Multiple = @Multiple); 

RETURN @ImpInt

END;
GO

このUDFはSQL Server 2014で完全に機能します。これをAzureデータウェアハウスで作成すると、作成されますが、クエリを実行しても機能しません。 NULLを返します。ターゲットテーブルが存在するかどうかなど、明らかなことをすべて確認しました。私はAzureデータウェアハウスの CREATE FUNCTION ドキュメントを確認しましたが、intdecimalに変換するサンプルUDFがあります。これはAzure DWで問題なく動作します。 selectを持つ単純な関数を書いた瞬間、失敗しました。残念ながら、ここでのAzureのドキュメントはあまり役に立ちません。この問題に遭遇した人がいるかどうか疑問に思いました。はいの場合、どのように解決しましたか?

私は別のユースケースをテストしたところ、うまくいきませんでした:

CREATE function [dbo].[fn_GetNumberBusinessDays] 
(
    @StartDate datetime,
    @EndDate Datetime
)
returns int
as 
begin 

DECLARE @NDAYS INT = 0
SELECT @NDAYS = 
  ISNULL( (DATEDIFF(dd, @StartDate, @EndDate) + 1)
  -(DATEDIFF(wk, @StartDate, @EndDate) * 2)
  -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
  -(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END) - 1 ,0) + 1


 SELECT @NDAYS = @NDAYS - COUNT(*)
 FROM dbo.FedHolidays
 WHERE DateOfHoliday BETWEEN @StartDate AND @EndDate


 RETURN @NDAYS
end
GO
7
RK Kuppala

Azure DWの関数は、ユースケースのようにテーブルにアクセスするselectステートメントをサポートしていません。 CREATE FUNCTION(SQLデータウェアハウス) を参照してください。

function_body
データベースデータ(テーブルまたはビュー)を参照しない一連のTransact-SQLステートメントが関数の値を定義することを指定します。

関数がDWで作成されていることを再確認できますか?

6
Jovan MSFT

Azure SQL Data Warehouseは、UDFのサポートに制限があります。構文SELECT @var =はまだサポートされていません。代わりに、DECLARE @var int =またはSET @var =を使用する必要があります。 SQL DW UDFは、まだユーザーテーブルのクエリもサポートしていません。新機能に投票するには フィードバックページ を使用してください。

6
Sonya Marshall

Azure SQL Data Warehouseには、互換性のないデータ型、インライン関数、ヒントの使用、RETURNステートメントの使用などの問題をピックアップするデータウェアハウス移行ユーティリティ(利用可能 こちら )があります。 INSERT ... EXECおよび他の多く:

Example Database Compatibility report

残念ながら、それはテーブルを参照するスカラー関数をピックアップせず、実際にそうするべきです。ただし、特定の関数の場合、それは単なるビュー(または別のテーブル)でもかまいません。たとえば、

CREATE VIEW dbo.vw_ImpliedRates
AS
SELECT 1 term, [1] impliedRate, Multiple
FROM  dbo.ImpliedRate 
UNION ALL
SELECT 2 term, [2], Multiple
FROM  dbo.ImpliedRate 
UNION ALL
SELECT 3 term, [3], Multiple
FROM  dbo.ImpliedRate 
UNION ALL
SELECT 4 term, [4], Multiple
FROM  dbo.ImpliedRate;
GO

CREATE TABLE dbo.test
(
    Multiple    FLOAT NOT NULL,
    Term        INT NOT NULL
);
GO

INSERT INTO dbo.test ( Multiple, Term )
VALUES
    ( 0.001, 1 ), ( 0.001, 2 ), ( 0.001, 3 ), ( 0.001, 4 );
GO


SELECT impliedRate, v.Multiple
FROM dbo.test t
    INNER JOIN dbo.vw_ImpliedRates v
        ON t.Multiple = v.Multiple
       AND t.Term = v.Term;

SELECT *
FROM dbo.vw_ImpliedRates
WHERE Multiple = 0.001
  AND Term = 2

私はこれをAzure SQL Data Warehouseで試してみましたが、完全にうまくいきました。

また、SQL Serverのスカラー関数は、テーブルに対して呼び出されたときに適切にスケーリングされないことも知っておく必要があります。AzureSQLデータウェアハウスに適したボリューム(つまり、数十億行)がある場合は、スカラー関数の使用を再考する必要があります。とにかく。たとえば、CTASを使用してより多くの手続き型コードを記述することは、この非常に強力なプラットフォームを適切に使用できる優れたアプローチです。

2
wBob