2012-01-18 7 views
0

私は3つの主キーをexに渡すことができるSQL Server機能を探しています。 @testIDバージョンが比較されている整数と複数の列がある@maxID@minIDバージョン値の間にある場合、結果は1(真)であると複数の重み付き列を比較するスカラー関数

functionFoo (@maxID, @minID, @testID) 

@maxIDがNULLの場合は、@testIDの列が@minIDの列より大きいかどうかをチェックするなど、オープンエンドの比較を処理できるようにしたいと思います。または、@minIDがNULLの場合、@testID列が@maxID列より小さいかどうかをチェックします。

ソフトウェアのバージョンを比較するという、このような複雑な例を考えてみましょう。バージョン管理された複数のソフトウェアがあるとします。たとえば、バージョン1.6.6.978.73のsoftware1があり、バージョン1.5.9.7とバージョン1.6.7の間にあるかどうかを判断するSQL Server関数が必要になったとします。私のテーブルは、

以下のソフトウェアVersion1列は常に Version2列(例えば、バージョン2.0 1.99999より高い)よりも高いが加重される

ID Version1 Version2 Version3 Version4 Version5 
1 1  6  6  978  73 
2 1  5  9  7  NULL 
3 1  6  7  NULL  NULL 

ように設定されます。私は各列を調べて比較を行いましたが、結果があいまいであれば次の列に移動して比較をやり直しますが、読みづらいと思います。より良い/より簡単な方法がありますか? SQL Serverの組み込み関数が欠けていますか?アルファベット順でソートするのと非常によく似ています。再帰的な性質は、最初の比較が決定的な結果をもたらさない場合には、一層深く進むことです。

+0

あなたは洗練されたソリューションを望んでいるようですが、バージョン番号のどれもが10^4のようなものを超えていなければ、 COLLESCE(バージョン5、0)* 10^4 + COALESCE(バージョン3、0)* 10^8 + COALESCE(バージョン2、0)* 10^12 + COALESCE(バージョン1、0)* 10^16比較を上回る/下回るようにする。 –

+0

数字が約500を超えることはないので、私はこのような解決策を考えました。私はもっ​​とクリーンな方法があることを望んでいました。なぜなら、いつかはその時点を超えて論理が壊れてしまったからです。 – Stormchao

答えて

0

この問題への私のアプローチはしました3つのレコードを選択し、ORDER BY句を使用してソートします。次に、レコードにROW_NUMBER()を適用し、単純なif文で関数の出力を決定します。この関数は@testIDが@minIDと@maxIDの間にあることを確認するだけなので、@maxIDは@minIDより小さくて差し支えありません。それは私が必要としたもののために大丈夫でした。私はそれを行う最良の方法であるかどうかはわかりませんが、それは非常に読みやすく論理は理にかなっていると思います。

CREATE FUNCTION dbo.fnCompareSoftware 
--Provide the function with the minID and maxID and the testID and it will determine if the testID is between the minID and maxID 
(
@minID int, 
@maxID int, 
@testID int 
) 
RETURNS bit 
AS 
BEGIN 
DECLARE @rowTestNumber int 
--inclusiveness 
if @minID = @testID 
    BEGIN 
    RETURN 1 
    END 
if @maxID = @testID 
    BEGIN 
    RETURN 1 
    END 

SELECT @rowTestNumber = rowNumber FROM (
    --SELECT the 3 softwareID, then order them properly, then give them row numbers. Based on the results we can determine the result. 
    SELECT 
    ROW_NUMBER() OVER (ORDER BY Version1,Version2,Version3,Version4,Version5 ASC) AS rowNumber, Software.ID,Text 
    FROM Software 
    WHERE ID IN(@minID,@maxID,@testID) 
) as Results 
WHERE ID = @testID 

--If minID is 0, then we are checking if the @testID is less than the @maxID. If so, @maxID will have the number 2 spot, and @testID will be #1 
if @minID = 0 AND @maxID !=0 AND @rowTestNumber = 1 
    BEGIN 
    RETURN 1 
    END 
--If maxID is 0, then we are checking if the @testID is more than the @minID. If so, @minID will have the number 1 spot, and @testID will be #2 
if @minID != 0 AND @maxID =0 AND @rowTestNumber = 2 
    BEGIN 
    RETURN 1 
    END 
if @minID != 0 AND @maxID !=0 AND @rowTestNumber = 2 
    BEGIN 
    RETURN 1 
    END 
--else we return 0 
RETURN 0 
END 
GO 
; 
0

ご迷惑をおかけして申し訳ありません。私はきちんとした方法はないと思う。バージョンを文字列にキャストすると役に立ちます。

CREATE FUNCTION VerCast(@Num1 INT, @NumHelper INT) 
RETURNS VARCHAR(100) 
AS 
BEGIN 
RETURN COALESCE(REPLICATE('0', 
    LEN(CAST(@NumHelper AS VARCHAR(100))) - LEN(CAST(@Num1 AS VARCHAR(100)))), '') + CAST(@Num1 AS VARCHAR(100)) 
END 

その後VERCAST(a.Verion1、b.Verion1)+ VERCAST(a.Version2、b.Version2)に比較する...など

VERCAST(12,123) => 012 
VERCAST(123,12) => 123 
関連する問題