sql >> Database >  >> RDS >> Sqlserver

Buitenste Toepassen Onverwachte terugkerende kolommen NIET NULL wanneer geen overeenkomst

Dit is zeker een bug in het product.

Een soortgelijke bug is al gemeld en gesloten als "Lost niet op" .

Inclusief deze vraag, het gekoppelde connect-item en een andere twee vragen op deze site Ik heb vier gevallen van dit soort gedrag gezien met inline TVF's en OUTER APPLY - Ze waren allemaal van het formaat

OUTER APPLY dbo.SomeFunction(...) F

En gaf correcte resultaten terug wanneer geschreven als

OUTER APPLY (SELECT * FROM dbo.SomeFunction(...)) F

Dit lijkt dus een mogelijke oplossing.

Voor de vraag

WITH Test AS
(
       SELECT 12 AS PropertyID,
              $350000 AS Ap1,
              350000 AS Ap2
)
SELECT LP.*
FROM Test T
OUTER APPLY dbo.TVFTest
(
       T.PropertyID,
       T.Ap1,
       T.Ap2
) LP;

Het uitvoeringsplan ziet eruit als

En de lijst met outputkolommen in de uiteindelijke projectie is. Uitdr1000, Uitdr1001, Uitdr1003, Uitdr1004.

Er zijn echter slechts twee van die kolommen gedefinieerd in de tabel met constanten rechtsonder.

De letterlijke $350000 wordt gedefinieerd in de tabel met constanten in de rechterbovenhoek (Expr1001). Dit wordt dan aan de buitenkant samengevoegd met de tabel met constanten rechtsonder. Aangezien er geen rijen overeenkomen met de join-voorwaarde, worden de twee kolommen die daar zijn gedefinieerd (Expr1003, Expr1004) correct geëvalueerd als NULL. dan voegt de compute scalaire waarde de letterlijke 12 toe in de gegevensstroom als een nieuwe kolom (Expr1000) ongeacht het resultaat van de outer join.

Dit is helemaal niet de juiste semantiek. Vergelijk met het (juiste) plan wanneer de inline TVF handmatig inline is.

WITH Test
     AS (SELECT 12      AS PropertyID,
                $350000 AS Ap1,
                350000  AS Ap2)
SELECT LP.*
FROM   Test T
       OUTER APPLY (SELECT KeyID,
                           MatchValue1,
                           MatchValue2,
                           CASE
                             WHEN MatchValue1 <> MatchValue2
                               THEN 'Not equal'
                             ELSE 'Something else'
                           END AS MatchTest
                    FROM   (SELECT T.PropertyID AS KeyID,
                                   T.Ap1        AS MatchValue1,
                                   T.Ap2        AS MatchValue2) TestRow
                    WHERE  MatchValue1 <> MatchValue2) LP 

Hier zijn de kolommen die in de uiteindelijke projectie worden gebruikt Expr1003, Expr1004, Expr1005, Expr1006 . Deze worden allemaal gedefinieerd in de constante scan rechtsonder.

In het geval van de TVF lijkt het al heel vroeg mis te gaan.

OPTION (RECOMPILE, QUERYTRACEON 3604, QUERYTRACEON 8606); geeft aan dat de invoerboom voor het proces al onjuist is. Uitgedrukt in SQL is het zoiets als.

SELECT Expr1000,
       Expr1001,
       Expr1003,
       Expr1004
FROM   (VALUES (12,
               $350000,
               350000)) V1(Expr1000, Expr1001, Expr1002)
       OUTER APPLY (SELECT Expr1003,
                           IIF(Expr1001 <> Expr1003, 
                               'Not equal', 
                               'Something else') AS Expr1004
                    FROM   (SELECT CAST(Expr1002 AS MONEY) AS Expr1003) D
                    WHERE  Expr1001 <> Expr1003) OA 

De volledige uitvoer van die traceervlag is als volgt (en 8605 toont in principe dezelfde boom.)

*** Input Tree: ***
        LogOp_Project COL: Expr1000  COL: Expr1001  COL: Expr1003  COL: Expr1004 

            LogOp_Apply (x_jtLeftOuter)

                LogOp_Project

                    LogOp_ConstTableGet (1) [empty]

                    AncOp_PrjList 

                        AncOp_PrjEl COL: Expr1000 

                            ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=12)

                        AncOp_PrjEl COL: Expr1001 

                            ScaOp_Const TI(money,ML=8) XVAR(money,Not Owned,Value=(10000units)=(-794967296))

                        AncOp_PrjEl COL: Expr1002 

                            ScaOp_Const TI(int,ML=4) XVAR(int,Not Owned,Value=350000)

                LogOp_Project

                    LogOp_Select

                        LogOp_Project

                            LogOp_ConstTableGet (1) [empty]

                            AncOp_PrjList 

                                AncOp_PrjEl COL: Expr1003 

                                    ScaOp_Convert money,Null,ML=8

                                        ScaOp_Identifier COL: Expr1002 

                        ScaOp_Comp x_cmpNe

                            ScaOp_Identifier COL: Expr1001 

                            ScaOp_Identifier COL: Expr1003 

                    AncOp_PrjList 

                        AncOp_PrjEl COL: Expr1004 

                            ScaOp_IIF varchar collate 53256,Var,Trim,ML=14

                                ScaOp_Comp x_cmpNe

                                    ScaOp_Identifier COL: Expr1001 

                                    ScaOp_Identifier COL: Expr1003 

                                ScaOp_Const TI(varchar collate 53256,Var,Trim,ML=9) XVAR(varchar,Owned,Value=Len,Data = (9,Not equal))

                                ScaOp_Const TI(varchar collate 53256,Var,Trim,ML=14) XVAR(varchar,Owned,Value=Len,Data = (14,Something else))

            AncOp_PrjList 

*******************


  1. Hoe onderliggende tabellen te vinden die overerven van een andere tabel in PSQL

  2. Hoe long int efficiënt te converteren naar gestippelde quad IP in bash

  3. Hoe repareer ik deze lus om afbeeldingen uit mijn database weer te geven met behulp van bootstrap-carrousel?

  4. Toon boommenu van geselecteerde ouder