Avatar billede hermanlaksko Nybegynder
19. december 2007 - 07:45 Der er 9 kommentarer

Status linie fra stored procedure

Jeg har en adp front hvor jeg gerne vil vise status over hvad der sker i en stored procedure.
Proceduren tager ca. 1 min. for at gennemløbe og behandle alle poster det kunne derfor være rart for brugeren at kunne se forløbet fx. på access/adp statuslinie fx. angivet med et tal eller lign.

Er der nogen der ved om dette kan lade sig gøre, på forhånd tak.
Avatar billede hrc Mester
19. december 2007 - 14:07 #1
Har du overvejet at splitte operationerne op i under-SP's og derved lave en løbende status?
Avatar billede hrc Mester
19. december 2007 - 14:10 #2
Alternativt kan du måske skrive status til en logtabel og fra din ADP-front polle denne for fremskridt. Hvis du har det pakket ind i en transaktion må du lave en "named transaction" på denne operation.
Avatar billede hermanlaksko Nybegynder
19. december 2007 - 14:38 #3
Nej jeg havde ikke gjort mig denne overvejelse.
Jeg må indrømme at jeg havde håbet på "en ting" der kunne levere informationer direkte tilbage til apd'n
Men dit løsning er da en mulighed - har du evt. et eksempel du kunne vise, på forhånd tak.
Avatar billede hrc Mester
20. december 2007 - 08:15 #4
I det første forslag forestiller jeg mig at dit program kalder hver enkelt del selv og laver status udfra den status der returneres. Det afhænger af din procedures opbygning om man kan splitte den op.

Det andet forslag er også simpelt. På strategiske steder i procedures skriver du status ned i en log-tabel som dit klientprogram poller, eksempelvis 2 gange i sekundet. Det største problem her er at få data at se hvis der er transaktioner i spil, for så vil data ikke ses før en commit - medmindre du laver en named transaktion til skrivning i log-tabellen:

  http://msdn2.microsoft.com/en-us/library/ms174377.aspx

Det er svært at demonstrere det mere detaljeret når jeg ikke kender din procedure.

Hvordan man laver en god polleralgoritme i din klient ved jeg ikke. Kender ikke akronymet ADP.

Bemærk, jeg er ingen haj udi MSSQL, så det er da meget muligt andre kan stampe smartere forslag op.

Bemærk i øvrigt, at bruger du ikke transaktioner, vil indførslen af disse nok reducere kørselstiden til en tredjedel.
Avatar billede hermanlaksko Nybegynder
20. december 2007 - 08:27 #5
ALTER PROCEDURE dbo.FindIncl  @EcDate DateTime, @Ret Int OUTPUT AS

SET NOCOUNT OFF
SET ANSI_WARNINGS OFF
SET CONCAT_NULL_YIELDS_NULL OFF
--DECLARE @EcDate DateTime
DECLARE @CurIncl AS Bit
DECLARE @TID AS NVarChar(50)
DECLARE @SumDis AS Money
DECLARE @SumRep AS MONEY
DECLARE @TotalCreditAmount As Money
DECLARE @CommitmentDate DateTime
DECLARE @CommitmentTerminationDate DateTime
DECLARE @BYN AS Bit
--Set @EcDate=GetDate()
DECLARE ReNew CURSOR FOR SELECT TOP 100 PERCENT TransactionID, SUM(TotalCreditAmount) AS Amount, CommitmentDate, CommitmentTerminationDate FROM EcRep GROUP BY TransactionID, CommitmentDate, CommitmentTerminationDate HAVING (SUM(TotalCreditAmount) > 0) ORDER BY TransactionID
OPEN ReNew
FETCH NEXT FROM ReNew INTO @TID, @TotalCreditAmount, @CommitmentDate, @CommitmentTerminationDate
WHILE @@fetch_status = 0
BEGIN
    --Chk a   
    SET @SumDis = (SELECT Sum(DisbursementAmount) AS Amount FROM EcDis WHERE DisbursementDate<= @EcDate AND TransactionID=@TID )
    SET @SumRep = (SELECT SUM(RepaymentAmount) AS Amount FROM EcRepay WHERE (RepaymentDate <= @EcDate) AND (Delay = 0)  AND TransactionID=@TID)
    IF (@SumDis) Is Null SET @SumDis=0
    IF (@SumRep) Is Null SET @SumRep=0
    If (@SumDis - @SumRep) >= 10  Set @CurIncl = 1
    --print 'Chk a '  + convert(nvarchar(50) ,(@SumDis - @SumRep))
    --Chk b
    IF (@TotalCreditAmount - @SumDis) > 1 And @CommitmentDate <= @EcDate And @CommitmentTerminationDate >= @EcDate SET @CurIncl = 1
    --print 'Chk b ' +  convert(nvarchar(50),(@TotalCreditAmount - @SumDis))
    --Chk c
    SET @SumRep=0
    SET @SumRep = (SELECT SUM(RepaymentAmount) AS Amount FROM EcRepay WHERE (RepaymentDate >= @EcDate) AND (Delay = 0) AND TransactionID=@TID)
    IF (@SumRep) Is Null SET @SumRep=0
    IF (@SumDis - @SumRep) < 0 SET @CurIncl = 1
    --print 'Chk c ' + convert(nvarchar(50),(@SumDis - @SumRep))
    IF @CurIncl=1 UPDATE EcRep Set Incl=1 WHERE TransactionID=@TID
    SET @SumDis=0
    SET @SumRep=0
    SET @CurIncl=0
    FETCH Next From ReNew Into  @TID, @TotalCreditAmount, @CommitmentDate, @CommitmentTerminationDate

END
Close ReNew
DEALLOCATE ReNew
SET @Ret = (SELECT COUNT(Incl) AS Incl FROM EcRep WHERE (Incl=1))
SET NOCOUNT ON
Avatar billede hermanlaksko Nybegynder
20. december 2007 - 08:29 #6
Din bemærkning om transaktioner lyder meget intressant kunne du komme med et forslag til dette nu hvor du kan se selve proceduren.
Avatar billede hrc Mester
22. december 2007 - 01:11 #7
Hvorfor vælger du top 100 percent? Er det ikke alt?

ALTER PROCEDURE dbo.FindIncl
@EcDate DateTime,
@TransID int,
@Ret int OUTPUT
AS
  SET NOCOUNT OFF
  SET ANSI_WARNINGS OFF
  SET CONCAT_NULL_YIELDS_NULL OFF

  --DECLARE @EcDate DateTime
  DECLARE @CurIncl AS Bit
  DECLARE @TID AS NVarChar(50)
  DECLARE @SumDis AS Money
  DECLARE @SumRep AS MONEY
  DECLARE @TotalCreditAmount As Money
  DECLARE @CommitmentDate DateTime
  DECLARE @CommitmentTerminationDate DateTime
  DECLARE @BYN AS Bit

  -- SET @EcDate = GetDate()
  DECLARE ReNew CURSOR FOR
    SELECT TOP 100 PERCENT TransactionID, SUM(TotalCreditAmount) AS Amount, CommitmentDate, CommitmentTerminationDate
      FROM EcRep
      GROUP BY TransactionID, CommitmentDate, CommitmentTerminationDate
      HAVING (SUM(TotalCreditAmount) > 0)
      ORDER BY TransactionID

  OPEN ReNew -- Open cursor

  FETCH NEXT FROM ReNew INTO @TID, @TotalCreditAmount, @CommitmentDate, @CommitmentTerminationDate
  WHILE @@fetch_status = 0
  BEGIN
    --Chk a
    SELECT @SumDis = Sum(DisbursementAmount)
      FROM EcDis
      WHERE (DisbursementDate<= @EcDate)
        AND (TransactionID=@TID)

    SELECT @SumRep = SUM(RepaymentAmount)
      FROM EcRepay
      WHERE (RepaymentDate <= @EcDate)
        AND (Delay = 0)
        AND (TransactionID=@TID)

    IF @SumDis Is Null
      SET @SumDis = 0

    IF @SumRep Is Null
      SET @SumRep=0

    If @SumDis - @SumRep >= 10
      SET @CurIncl = 1

    --print 'Chk a '  + convert(nvarchar(50) ,(@SumDis - @SumRep))
    --Chk b
    IF    (@TotalCreditAmount - @SumDis > 1)
      AND (@CommitmentDate <= @EcDate)
      AND (@CommitmentTerminationDate >= @EcDate)
      SET @CurIncl = 1

    -- PRINT 'Chk b ' +  CONVERT(nvarchar(50),(@TotalCreditAmount - @SumDis))

    --Chk c
    SET @SumRep = 0
    SELECT @SumRep = SUM(RepaymentAmount)
      FROM EcRepay
      WHERE (RepaymentDate >= @EcDate)
        AND (Delay = 0)
        AND (TransactionID=@TID)

    IF @SumRep IS NULL
      SET @SumRep = 0

    IF @SumDis - @SumRep < 0
      SET @CurIncl = 1

    --print 'Chk c ' + convert(nvarchar(50),(@SumDis - @SumRep))
    IF @CurIncl = 1
    BEGIN
      UPDATE EcRep
        SET Incl = 1
        WHERE (TransactionID = @TID)

      EXEC LogIt @TransID = @TransID, @LogText = "Writing"
    END
    ELSE
      EXEC LogIt @TransID = @TransID, @LogText = "Done"

    SET @SumDis = 0
    SET @SumRep = 0
    SET @CurIncl = 0

    FETCH Next From ReNew Into  @TID, @TotalCreditAmount, @CommitmentDate, @CommitmentTerminationDate
  END

  CLOSE ReNew -- Close and
  DEALLOCATE ReNew -- free

  SELECT @Ret = COUNT(Incl)
    FROM EcRep
    WHERE (Incl = 1)


---------------- o ----------------


CREATE PROCEDURE [dbo].[LogIt]

@TransID int,
@LogText varchar(50)
AS
BEGIN
  DECLARE @Err int
  DECLARE @TransName VARCHAR(10)

  SET @Err = 0
  SET @TransName = 'T' + CAST(@TransID as VARCHAR(9))

  BEGIN TRANSACTION @TransName
  INSERT INTO LOGTABLE (TransID, LogText) VALUES (@TransID, @LogText)
  SET @Err = @@ERROR

  IF @ERR = 0
    COMMIT TRANSACTION @TransName
  ELSE
    ROLLBACK TRANSACTION @TransName


... Noget i den retning. Det ser ikke ud til der er meget at hente ved at pakke operationen ind i en transaktion.

Som sagt, jeg er ingen haj - kunne ikke finde ud af at konvertere @TID til en varchar så det kunne logges.
Avatar billede hermanlaksko Nybegynder
22. december 2007 - 11:49 #8
Hej Hrc - jeg har ikke testet den - men det ser godt ud - læg et svar så jeg har mulighed for at give point - Tak for din flotte indsats  og god jul

Jeg benytter top 100 percent fordi jeg laver en sortering på transactionid.... jeg syntes at det en en underlig ide, men jeg får at vide, fra peoceduren, at den ikke kan sortere, hvis der ikke er angivet en procent...
Sql er lidt gl. dags og mystisk på mange områder, det virker lidt som om sql sproget/udviklingen gik i stå engang i 80erne ;-)
Tag fx. håndteringen af datoer, det er jo næsten en kamp hver gang og det på trods af at tid jo er den af de demintioner vi alle befinder os i, besynderligt :-D
Avatar billede hrc Mester
22. december 2007 - 22:03 #9
Det er med SQL som med religioner. Man kan ikke få revisioner nok. Personligt kunne jeg godt tænke mig en standard der bl.a. indeholdt alter table <tabel> rename ...
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