Avatar billede petercal Nybegynder
31. oktober 2002 - 10:11 Der er 10 kommentarer og
1 løsning

Returneret data fra stored procedure ?

Jeg har et problem med data returneret fra en stored procedure. Jeg bruger proceduren til at udføre en helt speciel sortering og det virker fint. Jeg har dog
konstateret at hvis der returneres store datamængder kan der gå kludder i sorteringen. Er nogen her bekendt med om der er begrænsninger i f.eks brugen af temp tabeller og cursors ?
Feltet [ORGDATA] [varchar] (2048)indeholder fra 300-1500 bytes og det er når der er mange data i dette delt at det går galt.
Har nogen en ide ?


proceduren sorterer i dato/tid men samler records med samme CID


CREATE PROCEDURE RapportF1
@monb    VARCHAR(28), -- fnummer
@sdate    VARCHAR(6),  -- startdato
@stime    VARCHAR(6),  -- starttid
@edate    VARCHAR(6),  -- slutdato
@etime    VARCHAR(6),  -- sluttid
@raptype  INT,        -- raptype
@SpA      VARCHAR(28), -- speciel søgning1
@SpB      VARCHAR(28)  -- speciel søgning2
                         
                           
AS

  DECLARE  @cid1 VARCHAR(8),
            @SQLStatement NVARCHAR(255)
 
CREATE TABLE [dbo].[#tmpresult] (
[UID] [int] IDENTITY (1, 1) NOT NULL, 
[NE] [char] (2) ,
[DATO] [char] (6) ,
[TID] [char] (6)  ,
[MONB] [varchar] (28) ,
[CID] [varchar] (14)  ,
[CTYPE] [varchar] (10) ,
[CTR] [varchar] (10)  ,
[IROUTE] [varchar] (8) ,
[OROUTE] [varchar] (8) ,
[FC] [char] (2)  ,
[ANB] [varchar] (28)  ,
[BNB] [varchar] (28) ,
[OCN] [varchar] (28)  ,
[RDN] [varchar] (28)  ,
[RDN1] [varchar] (28) ,
[CBN] [varchar] (28)  ,
[ACAT] [char] (2)  ,
[EOS] [varchar] (5)  ,
[TMR] [char] (2)  ,
[ENQ] [varchar] (3) ,
[CAW] [varchar] (3) ,
[DEV] [varchar] (15) ,
[MCNB] [varchar] (28) ,
[RCODE] [varchar] (3) ,
[CAU] [varchar] (40)  ,
[INFO] [varchar] (40),
[SQLTIME] [varchar] (20),
[HOSTID] [varchar] (16) ,
[ORGDATA] [varchar] (2048)  ) ON [PRIMARY]

-- UID er vigtig for at kunne sortere til sidst  --
--lokale #temp tabeller slettes automatisk og kan håndtere flere brugere samtidig

  SET NOCOUNT ON

  -- hent de records som rapporten skal indeholde
  -- og gem dem i en midlertidig tabel
SELECT * INTO #tmptable1 FROM li_data
WHERE MONB=@monb AND (DATO >= @sdate AND TID >= @stime)
                AND (DATO <= @edate AND TID <= @etime)
                ORDER BY DATO,TID

-- opret cursor og hent alle CID der skal sorteres efter men uden dubletter
-- hvis der er speciel søgning på skal kun
  -- de CID der hører til disse med
  IF (@spA > '') AND (@spB = '')
  -- speciel søgning1
    SET @SQLStatement = 'DECLARE Cursor1 CURSOR FOR SELECT DISTINCT CID FROM #tmptable1 WHERE ANB ='+@spA
  IF (@spA = '') AND (@spB > '')
  -- speciel søgning2
    SET @SQLStatement = 'DECLARE Cursor1 CURSOR FOR SELECT DISTINCT CID FROM #tmptable1 WHERE BNB ='+@spB
  IF (@spA > '') AND (@spB > '')
  -- speciel søgning på A og B nummer
    SET @SQLStatement = 'DECLARE Cursor1 CURSOR FOR SELECT DISTINCT CID FROM #tmptable1 WHERE ANB ='+@spA+' AND BNB='+@spB

  IF (@spA = '') AND (@spB = '')
  -- normal søgning
    SET @SQLStatement = 'DECLARE Cursor1 CURSOR FOR SELECT DISTINCT CID FROM #tmptable1'
  -- udfør SQL
  EXECUTE sp_executesql @SQLStatement

  -- åbner recordsættet
  OPEN Cursor1

  -- hent første post
  FETCH NEXT FROM Cursor1 INTO @CID1
  -- vælg alle poster med denne CID og gem i resultat tabellen 
  INSERT INTO #tmpresult
  SELECT * FROM #tmptable1 WHERE CID=@cid1

  -- læs alle CID igennem
  WHILE @@FETCH_STATUS = 0
  BEGIN --loop
    -- hent næste post
    FETCH NEXT FROM Cursor1 INTO @CID1
    -- nødvendig break, ellers vises sidste post 2 gange
    IF @@FETCH_STATUS = -1
      BREAK
    -- vælg alle poster med denne CID og gem i resultat tabellen
    INSERT INTO #tmpresult
    SELECT * FROM #tmptable1 WHERE CID=@cid1
  END

  CLOSE Cursor1
  DEALLOCATE Cursor1

  -- her bestemmer rapporttypen hvilke felter der skal returneres
  IF @raptype = 1 SELECT DATO,TID,MONB,CTYPE,ANB,BNB,OCN,RDN,RDN1,ENQ,CAW,FC,MCNB,NE,CID,ORGDATA,HOSTID,SQLTIME FROM #tmpresult
          ORDER BY UID
  IF @raptype = 2 SELECT DATO,TID,MONB,CTYPE,ANB,BNB,OCN,RDN,RDN1,CBN,ENQ,CAW,FC,ACAT,MCNB,RCODE,IROUTE,OROUTE,NE,CID,
                        CTR,DEV,TMR,EOS,CAU,ORGDATA,HOSTID,SQLTIME FROM #tmpresult  ORDER BY UID
                   
RETURN
GO
Avatar billede ocp Nybegynder
31. oktober 2002 - 11:05 #1
Hvordan går det ged i sorteringen? Eksempel?
Avatar billede petercal Nybegynder
31. oktober 2002 - 12:06 #2
proceduren sorterer normalt i dato/tid men samler
records med samme CID
når fejlen opstår er det totalt blandet sammen

dato    tid    cid
021001  1000  0001
021001  1005  0001
021001  1007  0001
021001  1008  0001
021001  1002  0002
021001  1003  0002
021001  1004  0002
021001  1005  0002
Avatar billede ocp Nybegynder
31. oktober 2002 - 12:40 #3
Jamen det passer jo da CID'et skifter netop i 5. linie?
Avatar billede petercal Nybegynder
31. oktober 2002 - 17:15 #4
Det var kun et konstrueret eks. på hvordan sorteringen foregår, og det virker også fint, bortset fra når der er MANGE data i det returnerede recordset. dvs når jeg spørger på en lang periode.
Avatar billede ocp Nybegynder
31. oktober 2002 - 19:44 #5
Jeg har brug for et eller andet eksempel hvor det rent faktisk GÅR galt - ellers kan jeg jo ikke se hvor problemet ligger.
Avatar billede petercal Nybegynder
31. oktober 2002 - 19:58 #6
Det kan jeg desværre ikke give, da dette er "firma data", mit spørgsmål går også mest på om der er begrænsninger i f.eks cursors eller brug af temporære tabeller i stored procedures.
Avatar billede kichian Nybegynder
02. november 2002 - 12:59 #7
En TEMP-tabel har ingen specielle begrænsninger i forhold til en alm. tabel. For en TEMP tabel oprettes i TEMPDB som en alm. tabel, og du arbejder så med et synonym for denne.

Det er vel fint nok at du forventer en dato,tid,cid sortering. Problemet er vel bare at du skriver ORDER BY UID.
Avatar billede petercal Nybegynder
02. november 2002 - 13:36 #8
UID som autogenererer med +1 er netop med for ikke at ødelægge sorteringen igen, når jeg indsætter data i result tabellen. 
Det er ikke er spørgsmål om antal returnerede records men om datamængden der returneres.
Avatar billede kichian Nybegynder
02. november 2002 - 21:52 #9
Ups. Så ikke at UID var et Identity-felt.
Jeg kan dog ikke forstå at du bruger dette, da du alligevel antager at en table-scan af #tmptable1 returnerer rækker i indsat rækkefølge. Noget som jeg iøvrigt også ville antage.

Jeg kan ikke forklare hvorfor sorteringen ikke bliver bibeholdt. Men jeg vil tro at du skal se nærmere på værdierne i dato og tid. Det kunne jo være at de var atypiske(ikke helt hvad du forventede) for de rækker hvor der er en større datamængde.

Medmindre at din Procedure kun er et eksempel bør du iøvrigt skrive den om.
CID bør indgå i ORDER BY i den første select. Derudover bør du undgå cursere medmindre at data ikke kan behandles som mængder. Og der kan de i din procedure. En simpel ORDER BY dato,tid,cid vil klare jobbet meget hurtigere.

Hvis der skal foretages flere operationer på temp-tabellen kan der sagtens lægges et index på.
Avatar billede petercal Nybegynder
03. november 2002 - 10:04 #10
Jeg er nødt til at bruge denne metode for at sortere rigtigt.
Se herunder i eks, bemærk at de 2 hændelser (CID) tidsmæssigt er flettet ind i hinanden. Det kan ikke gøres med 1 select alene.

dato    tid    cid
021001  1000  0001
021001  1005  0001
021001  1007  0001
021001  1008  0001
021001  1002  0002
021001  1003  0002
021001  1004  0002
021001  1005  0002

Men jeg blev opmærksom på at : INSERT INTO #tmpresult SELECT * FROM #tmptable1 WHERE CID=@cid1 måske bør have en ORDER BY DATO,TID på.
Det vil jeg prøve.

Udover dette er det ikke fejl i mine dato/tid felter der ødelægger sorteringen. Jeg er stadig på bar bund men mit egentlige problem,
men jeg vil prøve at fjerne feltet ORGDATA (2048) fra proceduren som
forsøg.
Avatar billede petercal Nybegynder
28. november 2002 - 21:07 #11
Jeg har selv fået det løst ved at indføre order by dato,tid på min cursor at fjerne min DISTINCT. Nu checker jeg så istedet for dubletter inden jeg indsætter i min #result. Samtidig har det hjulpet MEGET på hastigheden at indsætte ét INDEX på #tmptable1 og på #result.
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
Kategori
Computerworld tilbyder specialiserede kurser i database-management

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