2
私は確かに答えはいいですが、私は二重チェックしたいです。方法がある場合、実際にコードを記述する必要はありませんが、メソッドの提案が役立つ可能性があります。私はサブクエリなどで1つの大きな選択を試みましたが、正しいレコードを選択する方法を理解できません。このスカラー関数からインラインテーブル値関数を作成することは可能ですか?
逆の関係を得るために、テーブル自体に戻ってきてください。以下のコードは単なるテストサンプルです。
これはテストのために、いくつかのレコードを持つテーブルです
create function [dbo].[fnUOMFactor_Inline] (
@ItemID nvarchar(20)
, @FromUnit nvarchar(10)
, @ToUnit nvarchar(10)
)
returns numeric(28,12)
as
begin
declare @Factor numeric(28,12)
if @FromUnit = @ToUnit
set @Factor = 1
-- Simple 1-step
if @Factor is null
select @Factor = factor
from dbo.UnitConvertTest
WHere itemid = @ItemID
and fromunit = @FromUnit
and tounit = @ToUnit
-- Inverted 1-step
if @Factor is null
select @Factor = 1/factor
from dbo.UnitConvertTest
Where itemid = @ItemID
and fromunit = @ToUnit
and tounit = @FromUnit
if @Factor is null
select @Factor = uc1.factor * uc2.factor
from dbo.UnitConvertTest uc1
join dbo.UnitConvertTest uc2 on uc1.itemid = uc2.itemid
and uc1.tounit = uc2.fromunit
where uc1.itemid = @ItemID
and uc1.fromunit = @FromUnit
and uc2.tounit = @ToUnit
and uc1.factor <> 0
and uc2.factor <> 0
-- Inverted 2-step
if @Factor is null
select @Factor = 1/(uc1.factor * uc2.factor)
from dbo.UnitConvertTest uc1
join dbo.UnitConvertTest uc2 on uc1.itemid = uc2.itemid
and uc1.tounit = uc2.fromunit
Where uc1.itemid = @ItemID
and uc1.fromunit = @ToUnit
and uc2.tounit = @FromUnit
-- Complex 2-step (same fromunit)
if @Factor is null
select @Factor = uc1.factor/uc2.factor
from dbo.UnitConvertTest uc1
join dbo.UnitConvertTest uc2 on uc1.itemid = uc2.itemid
and uc1.fromunit = uc2.fromunit
Where uc1.itemid = @ItemID
and uc1.tounit = @ToUnit
and uc2.tounit = @FromUnit
-- Complex 2-step (same tounit)
if @Factor is null
select @Factor = uc1.factor/uc2.factor
from dbo.UnitConvertTest uc1
join dbo.UnitConvertTest uc2 on uc1.itemid = uc2.itemid
and uc1.tounit = uc2.tounit
Where uc1.itemid = @ItemID
and uc1.fromunit = @FromUnit
and uc2.fromunit = @ToUnit
-- Default
if @Factor is null
set @Factor = 1
return @Factor
end
ありがとうございます。
CREATE TABLE [dbo].[UnitConvertTest](
[FROMUNIT] [nvarchar](10) NOT NULL,
[TOUNIT] [nvarchar](10) NOT NULL,
[FACTOR] [numeric](28,12) NOT NULL,
[ITEMID] [nvarchar](20) NOT NULL,
) ON [PRIMARY]
insert into dbo.UnitConvertTest (FROMUNIT, TOUNIT, FACTOR, ITEMID)
Values ('CT','PT','40.00','TEST')
, ('RM','CT','10.00','TEST')
, ('RM','PT','400.00','TEST')
Select [dbo].[fnUOMFactor_Inline] ('Test','PT','RM')
天才、ありがとう!これまで、これを使って関数をインラインバージョンに書き直すことができました。私のテスト例は完全に動作します。私はいくつかのより大きなデータセットでそれを実行し、それは動作し、パフォーマンスの改善と思われた。私はそれをさらに大きなデータセットで実行しました。私は以下のエラーを受け取りました。私は関数の構造を見てそれがどのように可能であるか分かりません。任意のアイデア?エラー:サブクエリは1つ以上の値を返しました。サブクエリが=、!=、<, <= , >、> =、またはサブクエリが式として使用されているときは、これは許可されません。 –
私は問題がどこにあるのかわかります。あなたの例では、{computefallback}にサブクエリがあります。どこかで、結果が2行になるという基準を満たしています。私はそれらのシナリオでは、古い関数は "更新"のように動作し、ちょうど最初の値を選ぶと思います。おそらく、既存のロジックがやっているような要素を選択するためにMAX()を追加することができます。 –
古いコードにバグがありました。非確定的な値が選択されました...右、あなたはMAXまたはTOP 1 ORDER BYを使用することができます.... – usr