Avatar billede henrik_40 Juniormester
21. juni 2016 - 17:02 Der er 5 kommentarer og
1 løsning

Stored Procedure returnerer forkert select (cursor)

Hejsa
Jeg har lavet en Stored procedure, som returnerer en del-værdi, i forbindelse med definering af cursor:
DECLARE f_cursor CURSOR
    FOR SELECT ColumnLaengde, ColumnHoejde, ColumnBredde, ColumnCOD, ColumnLand, ColumnVaegt FROM  @TableFreight

Det er uønsket. Jeg ønsker slutværdien returneret, som er resultatet af en temporær tabel:
    SELECT  fp.FreightProductText,  k.*
    FROM #KolliTable k
    LEFT JOIN dan_FreightProduct fp on k.F_FreightProductID = fp.FreightProductID


Jeg regnede med jeg blot skulle skrive RETURN på det jeg ville returnere, men jeg for en forkert værdi. Jeg håber på hjælp.

Her er hele Stored Procedure:

ALTER PROCEDURE  [dbo].[DisplayFreigtsLimits]
(
    @TableFreight  FreightTableType READONLY
)
AS
BEGIN
    SET NOCOUNT ON;




/*
    DECLARE @FreightTable AS  TABLE
(
    laengde        INT            -- ColumnLaengde
    , hoejde    INT            -- ColumnHoejde
    , bredde    INT            -- ColumnBredde
    , CODprice    DECIMAL        -- ColumnCOD
    , country    VARCHAR(10)    -- ColumnLand
    , vaegt        INT            -- ColumnVaegt
   
);
*/


DECLARE @ExcludedList AS TABLE
(
    FreightLimitationID INT
)


SELECT TOP 0 * INTO #KolliTable  FROM  dan_FrieghtLimitation
SET IDENTITY_INSERT #KolliTable  ON

DECLARE @laengde AS INT
DECLARE @hoejde AS INT
DECLARE @bredde AS INT
DECLARE @vaegt AS INT
DECLARE @CODprice AS INT
DECLARE @country AS VARCHAR(5)


DECLARE @ShipmentWeight AS INT
DECLARE @ShipmentType AS INT
DECLARE @ShipmentVolume AS INT


SET @country = (SELECT TOP 1 ColumnLand FROM  @TableFreight);
SET @ShipmentWeight = ( SELECT  SUM(ColumnVaegt) FROM @TableFreight);
SET @ShipmentVolume = 0;

-- 1) beregn på  kolli niveau.
-- Bare een af kollierne, som ikke overholder limit-kravene, vil ekskludere et produkt.
DECLARE f_cursor CURSOR
    FOR SELECT ColumnLaengde, ColumnHoejde, ColumnBredde, ColumnCOD, ColumnLand, ColumnVaegt FROM  @TableFreight

    OPEN f_cursor
    FETCH NEXT FROM f_cursor
    WHILE @@FETCH_STATUS = 0


    BEGIN
    SET     @laengde =  (SELECT TOP 1 ColumnLaengde FROM  @TableFreight);
    SET    @hoejde = (SELECT TOP 1 ColumnHoejde FROM  @TableFreight)
    SET    @bredde = (SELECT TOP 1 ColumnBredde FROM @TableFreight)
    SET    @vaegt = (SELECT TOP 1 ColumnVaegt FROM @TableFreight)


    SET @ShipmentVolume = @ShipmentVolume + (@laengde * @hoejde * @bredde);




--     print @ShipmentVolume

        INSERT #KolliTable (FreightLimitationID,  F_county_Culture,  ShipmentPaymentType, CubicMesureConversion_Shipment
        , Min_Length_Kolli, Max_Length_Kolli, Min_Height_Kolli, Max_Height_Kolli, Min_Width_Kolli
        , Max_Width_Kolli, Min_Weight_Kolli, Max_Weight_Kolli, Min_Weight_Shipment, Max_Weight_Shipment
        , Max_Perimeter_Kolli, ExtraFee_Kolli, Max_COD_Shipment, F_FreightProductID )
        (
        SELECT FreightLimitationID,  F_county_Culture,  ShipmentPaymentType, CubicMesureConversion_Shipment
        , Min_Length_Kolli, Max_Length_Kolli, Min_Height_Kolli, Max_Height_Kolli, Min_Width_Kolli
        , Max_Width_Kolli, Min_Weight_Kolli, Max_Weight_Kolli, Min_Weight_Shipment, Max_Weight_Shipment
        , Max_Perimeter_Kolli, ExtraFee_Kolli, Max_COD_Shipment, F_FreightProductID
            FROM  dan_FrieghtLimitation lim WHERE lim.F_county_Culture LIKE @country

            --    AND (lim.ShipmentPaymentType = 1)

                AND (lim.Min_Length_Kolli  IS NULL OR lim.Min_Length_Kolli < @laengde)
                AND (lim.Max_Length_Kolli  IS NULL OR lim.Max_Length_Kolli > @laengde)

                AND (lim.Min_Height_Kolli IS NULL OR lim.Min_Height_Kolli < @hoejde)
                AND (lim.Max_Height_Kolli IS NULL OR lim.Max_Height_Kolli > @hoejde)

                AND (lim.Min_Width_Kolli IS NULL OR lim.Min_Width_Kolli < @bredde)
                AND (lim.Max_Width_Kolli IS NULL OR lim.Max_Width_Kolli > @bredde)

                AND (lim.Min_Weight_Kolli IS NULL OR lim.Min_Weight_Kolli < @vaegt)
                AND (lim.Max_Weight_Kolli IS NULL OR lim.Max_Weight_Kolli > @vaegt)

                AND (lim.Max_Perimeter_Kolli IS NULL OR lim.Max_Perimeter_Kolli > (@laengde + 2 * @bredde + 2 * @hoejde))

                AND (lim.Min_Weight_Shipment  IS NULL OR lim.Min_Weight_Shipment  < @ShipmentWeight)
                AND (lim.Max_Weight_Shipment  IS NULL OR lim.Max_Weight_Shipment  > @ShipmentWeight)

                AND (SELECT COUNT(*) FROM #KolliTable k WHERE k.FreightLimitationID = lim.FreightLimitationID) = 0
        )

        -- select  (@laengde + 2 * @bredde + 2 * @hoejde) AS OMKREDS

        FETCH NEXT FROM f_cursor


    CLOSE f_cursor;
    DEALLOCATE f_cursor;


    DROP TABLE #KolliTable


    -- SELECT * FROM #KolliTable
   
    -- Delete wrong insertion from Kolli
    DELETE FROM #KolliTable WHERE Min_Length_Kolli IS NOT NULL AND Min_Length_Kolli > ( select MIN(f.ColumnLaengde) from  @TableFreight f);
    DELETE FROM #KolliTable WHERE Max_Length_Kolli IS NOT NULL AND Max_Length_Kolli < ( select MAX(f.ColumnLaengde) from  @TableFreight f);

    DELETE FROM #KolliTable WHERE Min_Height_Kolli IS NOT NULL AND Min_Height_Kolli > ( select MIN(f.ColumnHoejde) from  @TableFreight f);
    DELETE FROM #KolliTable WHERE Max_Height_Kolli IS NOT NULL AND Max_Height_Kolli < ( select MAX(f.ColumnHoejde) from  @TableFreight f);

    DELETE FROM #KolliTable WHERE Min_Width_Kolli IS NOT NULL AND Min_Width_Kolli > ( select MIN(f.ColumnBredde) from  @TableFreight f);
    DELETE FROM #KolliTable WHERE Max_Width_Kolli IS NOT NULL AND Max_Width_Kolli < ( select MAX(f.ColumnBredde) from  @TableFreight f);

    DELETE FROM #KolliTable WHERE Min_Weight_Kolli IS NOT NULL AND Min_Weight_Kolli > ( select MIN(f.ColumnVaegt) from  @TableFreight f);
    DELETE FROM #KolliTable WHERE Max_Weight_Kolli IS NOT NULL AND Max_Weight_Kolli < ( select MAX(f.ColumnVaegt) from  @TableFreight f);





    SELECT  fp.FreightProductText,  k.*
    FROM #KolliTable k
    LEFT JOIN dan_FreightProduct fp on k.F_FreightProductID = fp.FreightProductID



    DROP TABLE #KolliTable

    END
END

GO
Avatar billede henrik_40 Juniormester
22. juni 2016 - 09:16 #1
Hej igen.
Har lavet en forsimplet Stored Procedure, som nemmere viser hvad mit problem er. Jeg håber det kan hjælpe Jer til at forstå min problematik og kunne hjælpe mig ;)



Problemet er stadig det samme. spyttes den første værdi ud fra select-sætningen.

SPYTTES UD:
DECLARE test_cursor CURSOR FOR
select fp.FreightProductText, lim.* from dan_FrieghtLimitation lim left join dan_FreightProduct fp on fp.FreightProductID = lim.F_FreightProductID
where F_county_Culture like 'fr-BE'

ØNSKES:

SELECT * FROM #KolliTable

DROP TABLE  #KolliTable











CREATE PROCEDURE SLETMIG
    -- Add the parameters for the stored procedure here
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
DECLARE @country AS VARCHAR(5)
DECLARE @laengde AS INT


SELECT TOP 0 * INTO #KolliTable  FROM  dan_FreightProduct
SET IDENTITY_INSERT #KolliTable  ON
DECLARE test_cursor CURSOR FOR
select fp.FreightProductText, lim.* from dan_FrieghtLimitation lim left join dan_FreightProduct fp on fp.FreightProductID = lim.F_FreightProductID
where F_county_Culture like 'fr-BE'

OPEN test_cursor
FETCH NEXT FROM test_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
SET @country = (
    SELECT  TOP 1  lim.F_county_Culture from dan_FrieghtLimitation lim left join dan_FreightProduct fp on fp.FreightProductID = lim.F_FreightProductID
    WHERE F_county_Culture like 'fr-BE');

    INSERT #KolliTable (FreightProductID, FreightProductText)  (select fp.FreightProductID, fp.FreightProductText from dan_FreightProduct fp)

    FETCH NEXT FROM test_cursor
   
END -- WHILE

CLOSE test_cursor
DEALLOCATE test_cursor


SELECT * FROM #KolliTable

DROP TABLE  #KolliTable


END
GO
Avatar billede Slettet bruger
24. juni 2016 - 08:16 #2
Når man bruger en cursor fetcher man normalt det data ind man looper over. Jeg forstår ikk dit brug af cursor når du alligevel sætter værdierne manuelt med en top 1.

OVervej lige hvad det er du skriver og hvad koden skal gøre.
Avatar billede Slettet bruger
24. juni 2016 - 08:18 #3
Derefter dropper du din kolli table, hvilket vil sige du ikke kan få data ud af den,,

For mig at se giver din kode ikke særlig meget mening, ellers må du være mere klar i spyttet på hvad du gerne vil,
Avatar billede henrik_40 Juniormester
24. juni 2016 - 09:40 #4
Hejsa PlaidDK
Jeg tror du misforstår koden.


Hejsa PlaidDK
Jeg tror du misforstår koden.

Min oprindelige kode har input af en Datatabel.



#KolliTable er en temporær tabel, som skal droppes til sidst.

Den bliver droppet efter mit ønskede resultat, som er:
SELECT * FROM #KolliTable
Select top 1 er kun for at få fat på feltet @country



SET @country = (SELECT TOP 1 ColumnLand FROM  @TableFreight);

Select top 1 er kun for at få landekoden sat.


Tilsvarende med de andre variable:
    SET    @laengde =  (SELECT TOP 1 ColumnLaengde FROM  @TableFreight);
    SET    @hoejde = (SELECT TOP 1 ColumnHoejde FROM  @TableFreight)
    SET    @bredde = (SELECT TOP 1 ColumnBredde FROM @TableFreight)
    SET    @vaegt = (SELECT TOP 1 ColumnVaegt FROM @TableFreight)




Cursoren løber igennem og udfylder #KolliTable. #KolliTable bliver korrekt udfyldt.




så problemet ligger kort sagt i at


SELECT  fp.FreightProductText,  k.*
    FROM #KolliTable k
    LEFT JOIN dan_FreightProduct fp on k.F_FreightProductID = fp.FreightProductID
ikke bliver output,

men select-statementen til at indsætte i kollitabellen bliver output.



SELECT FreightLimitationID,  F_county_Culture,  ShipmentPaymentType, CubicMesureConversion_Shipm.....
Bliver output



Jeg har fundet en løsning, som jeg vil anbefale , men UDEN brug af cursor (da cursor tit skaber problemer):
http://www.sqlbook.com/SQL/Avoiding-using-SQL-Cursors-20.aspx






"
For mig at se giver din kode ikke særlig meget mening, ellers må du være mere klar i spyttet på hvad du gerne vil
"


Jeg er glad for al den  hjælp jeg kan få, men bryder mig ikke om din nedværdigene ytring, som bunder i at du ikke selv forstår problemet, eller kan løse mit problem. Du kunne på almindelig dansk have bedt om uddybene forlaring.
Avatar billede Slettet bruger
24. juni 2016 - 09:58 #5
Det du skriver giver jo ingen mening, så kan man ikke hjælpe dig. Desuden giver din cursor ingen mening. Du skal fetch into når du laver din cursor, bare alene det gør at du ikke skal bruge den, når du ikke har det med.
Avatar billede Slettet bruger
24. juni 2016 - 10:00 #6
Jeg tror ikke du forstår din egen kode, når du ikke selv forstår brugen af cursor. Jeg kan godt se den ikke giver dig dit output, men det er jo ret klart når du ikke vælger det som output. Jeg vil anbefale dig at læse 40-461 bogen omkring SQL
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester