Ich bin mir ziemlich sicher, dass die Antwort Nein ist, aber ich möchte es überprüfen. Wenn es einen Weg gibt, müssen Sie es nicht wirklich programmieren, ein Vorschlag für eine Methode könnte helfen. Ich habe 1 große Auswahl mit Unterabfrage versucht, etc., aber ich kann nicht herausfinden, wie man es bekommt, um den richtigen Datensatz auszuwählen.Ist es möglich, eine Inline-Tabellenwertfunktion aus dieser Skalarfunktion zu erstellen?
Die Tabelle muss sich selbst wieder verbinden, um inverse Beziehungen zu erhalten. Der folgende Code ist nur ein Testbeispiel.
Danke
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
Dies ist eine Tabelle mit ein paar Datensätze zum Testen.
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')
Genie, danke! Bisher konnte ich die Funktion damit in eine Inline-Version umschreiben und mein Testbeispiel funktioniert einwandfrei. Ich habe es durch einige größere Datensätze geführt und es schien zu funktionieren und eine Leistungsverbesserung zu sein. Ich habe es dann durch einen noch größeren Datensatz geführt, und ich habe den Fehler unten erhalten. Ich bin nicht sicher, wie das möglich ist, basierend auf der Struktur der Funktion. Irgendeine Idee? Fehler: Unterabfrage gab mehr als 1 Wert zurück. Dies ist nicht zulässig, wenn die Unterabfrage =,! =, <, <= , >,> = oder wenn die Unterabfrage als Ausdruck verwendet wird. –
Ich denke, ich sehe, wo das Problem sein könnte. In Ihrem Beispiel habe ich die Unterabfrage in {computefallback}. Irgendwo erfülle ich die Kriterien, um 2 Reihen zu ergeben. Ich denke, die alte Funktion verhält sich in diesen Szenarien wie ein "Update" und wählt nur den ersten Wert aus. Vielleicht kann ich ein MAX() hinzufügen, um einen Faktor auszuwählen, wie es die existierende Logik tut. –
Der alte Code hatte dann einen Fehler. Es wurde ein nicht-deterministischer Wert gewählt ... Richtig, du kannst MAX oder TOP 1 ORDER BY verwenden. – usr