web-dev-qa-db-ja.com

intを返すSQLServer関数を作成するにはどうすればよいですか?

パラメータが特定の用語で始まるか、その用語が含まれているかをテストするSQL関数を作成しようとしていますが、それで始まりません。

基本的に、パラメーターが項で始まる場合、関数は0を返します。それ以外の場合、関数は1を返します。

これは私が持っている関数の骨であり、私が見つけた別の関数から適応しようとしています:

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS @value int -- this is showing an error, it seems to expect table but all I want is an int
(
    -- does this need to be here? If so, what should it be?
)

AS

BEGIN

    declare @field TABLE(Data nvarchar(50))

    insert into @field
        select Data from @fieldName

    if (Data like @searchTerm + '%') -- starts with
    begin       
        return 0
    end
    else if (Data like '%' + @searchTerm + '%' and Data not like @searchTerm + '%') -- contains, but doesn't start with 
    begin       
        return 1
    end

END

GO
8
DaveDev

戻り値の変数名は指定せず、その型のみを指定します。親は必要ありません。

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS int
AS
....

また;

select Data from @fieldName

動作しません。名前が変数に含まれているオブジェクトから選択するには、 動的SQL が必要です。

10
Alex K.

パラメータが特定の用語で始まるか、その用語が含まれているかをテストするSQL関数を作成しようとしていますが、それで始まりません。

私は次のことを想定しています:

  • @fieldNameは、実際にはテーブル名です(使用の試みから判断してください)。
  • @searchtermはあなたが探している用語です
  • Dataはテーブル@fieldNameの列です

上記のいずれかが正しくない場合、この答えはほとんど役に立たない。

選択クエリのテーブルはパラメータ化できないため、動的SQLを使用する必要があります。 「で始まる」とより一般的な「含む」を確認するために、2つの異なるバージョンの動的SQLが必要になります。呼び出しの結果を判別するには、動的SQLからの出力変数が必要になります。

余談ですが、INTはサイズの点で完全にやり過ぎです。状態が2つしかない場合(疑わしい)はBITが必要であり、状態が3つある場合(私が思うに)はTINYINTが必要です。今のところ、元の例に近づけるためにintを使用しますが、変更することを検討してください。

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)
RETURNS INT
AS
BEGIN

    DECLARE @startsWithResult INT,
            @containsResult INT
    DECLARE @startsWithSQL NVARCHAR(MAX) = N'SELECT @result=1 FROM ' + @fieldName + ' WHERE Data  LIKE '' + @searchTerm + '%'''
    DECLARE @containsSQL NVARCHAR(MAX) = N'SELECT @result=1 FROM ' + @fieldName + ' WHERE Data LIKE ''%' + @searchTerm + '%'''

   EXEC sp_ExecuteSQL @startsWithSQL, N'@result int output', @result = @startsWithResult OUTPUT

  IF @startsWithResult = 1
    RETURN 0

  EXEC sp_ExecuteSQL @containsSQL, N'@result int output', @result = @containsResult OUTPUT

  IF @containsResult = 1
    RETURN 1

END
0
Jamiec

参考までに、これはAlexKからの提案で実装された完全な関数です。

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS  int
AS
BEGIN
    if (@fieldName like @searchTerm + '%') -- starts with
    begin       
        return 0
    end
    else if ((@fieldName like '%' + @searchTerm + '%') and (@fieldName not like @searchTerm + '%')) -- contains, but doesn't start with 
    begin       
        return 1
    end

    return 1
END

GO
0
DaveDev

ここにはいくつかの問題があります。以下のコードにコメントを追加しました:

CREATE FUNCTION [dbo].[fnGetRelevance] 
(   
    @fieldName nvarchar(50),
    @searchTerm nvarchar(50)
)

RETURNS @value int --Returning an int is fine, but you don't need the @value variable
(
    --This isn't required (unless you're returning a table)
)

AS

BEGIN

    declare @field TABLE(Data nvarchar(50))

    --@fieldname is a varchar, not a table (is this where your error is coming from).     
    --If @fieldname is the name of a table you're going to need to exec a sql string and concat @fieldname into the string
    insert into @field
        select Data from @fieldName 

    --You need a variable to contain the value from Data 
    --(ie declare @Data and select @Data = Data)
    if (Data like @searchTerm + '%') -- starts with
    begin       
        return 0
    end
    else if (Data like '%' + @searchTerm + '%' and Data not like @searchTerm + '%') -- contains, but doesn't start with 
    begin       
        return 1
    end

END

これにより、達成しようとしていることに少し近づくはずです。

0
Jon Egerton