none
Formato dati per campo con valore predefinito @@dbts RRS feed

Risposte

  • salve,

    e' il principio dei funzionamenti in batch... il valore sara' aggiornato al termine di ogni batch, mentre tu utilizzi un rowconstructor multiplo per l'istruzione di insert.. mantieni le istruzioni separate,

    INSERT [dbo].[Tab] ([Id]) VALUES (n);
    INSERT [dbo].[Tab] ([Id]) VALUES (m);
    INSERT [dbo].[Tab] ([Id]) VALUES (y);
    INSERT [dbo].[Tab] ([Id]) VALUES (z);

    e torna a funzionare... :)

    continuo pero' a non comprendere bene il "significato" di tutto cio'...

    solitamente il rowversion si usa non a livello di proiezione (come filtro), ma a livello di aggiornamento come discriminate per il lock pessimistico a livello di riga completa... cio' consente, quindi, di scrivere qualche cosa simile a 

    CREATE PROCEDURE ... (
      @Id int,
      ... @params ..
      @RowVersion rowversion
    )
    AS BEGIN 
      DECLARE @r int;
      DECLARE @key varchar(10);
      BEGIN TRY
        UPDATE [dbo].[tabella]
        	SET ... = ...,
        	WHERE [Id] = @Id
        	   AND [ColRowVersion] = @RowVersion;
        
        SET @r = @@ROWCOUNT;
      
        IF (@r = 0) BEGIN			
          -- in caso di non aggiornamento righe notifica
          -- la possibile violazione di concorreza
          SELECT @msg = 'Impossibile aggiornare riga con Codice = [%s] in  [%s].' + CHAR(10) + 'Possibile conflitto di concorrenza.',
            @key = CONVERT(varchar(10), @Id); 
    
          RAISERROR (@msg, 16, 1, @Key , 'tabella xyz');
          END;
      
        RETURN 0;  
      END TRY
      
      BEGIN CATCH
        -- ritorna l'errore
        DECLARE @ErrorMSG varchar(2000);
        SET @ErrorMSG = ERROR_MESSAGE();
        RAISERROR (@ErrorMSG, 16, 1);
        RETURN -100;
      END CATCH
    END;

    questo per non verificare a livello di ogni singola colonna che il nostro aggiornamento collida con aggiornamenti parziali effettuati da altri nel caso si richieda, appunto, un lock pessimistico completo...

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    • Contrassegnato come risposta Mancini, mercoledì 31 ottobre 2012 22:07
    martedì 30 ottobre 2012 11:39
    Moderatore

Tutte le risposte

  • salve,

    come da http://msdn.microsoft.com/it-it/library/ms182776.aspx , il tipo di dato corrisponde a binary(8) o varbinary(8), ma puoi tranquillamente usare rowversion (http://msdn.microsoft.com/it-it/library/ms182776.aspx)

    non ho pero' compreso la tua indicazione "... che abbia come valore predefinito @@dbts ..."

    se definisci una colonna di tipo timestamp/rowversion, questa sara' sempre popolata automaticamente dallo storage engine, e questo ad ogni modifica... quindi non vedo perche' definire un valore predefinito..

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    lunedì 29 ottobre 2012 20:23
    Moderatore
  • non ho pero' compreso la tua indicazione "... che abbia come valore predefinito @@dbts ..."

    Scusami non sono stato chiaro,

    La tabella sarebbe composta da:

    ___ Tutti i suoi campi
    ___ Un campo chiamato "Row1"  con tipo dati  timestamp  senza valore predefinito
    ___ Un ulteriore campo chiamato "Row2" con tipo dati  ?????  con valore predefinito  @@dbts
    e senza NESSUNA altra operazione di modifica legata a variazioni del record

    L'obbiettivo è con CASE WHEN  verificare la differenza fra Row1  e Row2  per
    sapere se il record è stato modificato almeno 1 volta

    Ad oggi non sono ancora riuscito a rilevare la egualianza fra Row1 e Row2 e ho la
    sensazione che dipenda dal tipo di dati di Row2 ( in quanto non posso fare nulla su Row1 )

    La difficolta sta anche nel fatto che Row1  non è facilmente leggibile
    in quanto dato binario

    Grazie

    NB  Uso SQL2008R2    +  Access come applicativo

    .

    lunedì 29 ottobre 2012 21:05
  • Sembra che ho risolto,

    il formato richiesto è binary(8)  ( come del resto ci consiglia MSDN )

    Ho creato 1 tabella con un campo rowversion
    e 1 campo con valore predefinito (@@dbts + 1)

    Ho inserito 3 record e ho veruficato la egualianza fra i 2 campi
    Ho modificato 1 dei 3 record è ho verificato la disegualianza fra i 2 campi

    SET NOCOUNT ON;
    USE tempdb;
    GO
    -- Creo la tabella con rowversion e un campo di default @@dbts + 1
    CREATE TABLE [dbo].[Tab]
    (
     [Id] [int] NOT NULL,
     [Row1] [rowversion] NOT NULL,
     [Row2] [binary](8) NOT NULL
    ) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[Tab] ADD  CONSTRAINT [DF_Row2]  DEFAULT (@@dbts+(1)) FOR [Row2]
    GO
    --  Inserisco un po di dati
    INSERT [dbo].[Tab] ([Id]) VALUES (10)
    INSERT [dbo].[Tab] ([Id]) VALUES (21)
    INSERT [dbo].[Tab] ([Id]) VALUES (37)
    GO
    -- Verifico che  Row1 sia uguale a Row2
    SELECT     
    Id, 
    Row1, 
    Row2, 
    CAST(Row1 AS int) AS Row1x, 
    CAST(Row2 AS int) AS Row2x, 
    CASE WHEN Row1 = Row2 THEN 0 ELSE 111 END AS Confronto
    FROM         
    dbo.Tab
    GO
    -- Aggiorno 1 solo record
    UPDATE [dbo].[Tab]
    SET [Id] = 400
    WHERE [Id] = 21
    GO
    -- Verifico che in quel record Row1 sia diverso da Row2
    SELECT     
    Id, 
    Row1, 
    Row2, 
    CAST(Row1 AS int) AS Row1x, 
    CAST(Row2 AS int) AS Row2x, 
    CASE WHEN Row1 = Row2 THEN 0 ELSE 111 END AS Confronto
    FROM         
    dbo.Tab
    GO
    --  elimino la tabella da tempdb
    DROP TABLE [dbo].[Tab];
    GO
    -- Finito

    ______________________________________________________________________

    ______________________________________________________________________

    ______________________________________________________________________

    un ulteriore problema si ponr per gli inserinemti "massivi"

    .......
    INSERT [dbo].[Tab] ([Id])
    VALUES 
    (10),
    (21),
    (37);
    .........

    In questo caso  timestamp si aggiorna ad ogni riga
    mentre @@dbts non si aggiorna ma resta ancorato al valore della prima riga !!


    Se ho sbagliato qualcosa oppure se incompleto
    prego di farlo presente

     

    Grazie


    .

     


    martedì 30 ottobre 2012 01:27
  • salve,

    e' il principio dei funzionamenti in batch... il valore sara' aggiornato al termine di ogni batch, mentre tu utilizzi un rowconstructor multiplo per l'istruzione di insert.. mantieni le istruzioni separate,

    INSERT [dbo].[Tab] ([Id]) VALUES (n);
    INSERT [dbo].[Tab] ([Id]) VALUES (m);
    INSERT [dbo].[Tab] ([Id]) VALUES (y);
    INSERT [dbo].[Tab] ([Id]) VALUES (z);

    e torna a funzionare... :)

    continuo pero' a non comprendere bene il "significato" di tutto cio'...

    solitamente il rowversion si usa non a livello di proiezione (come filtro), ma a livello di aggiornamento come discriminate per il lock pessimistico a livello di riga completa... cio' consente, quindi, di scrivere qualche cosa simile a 

    CREATE PROCEDURE ... (
      @Id int,
      ... @params ..
      @RowVersion rowversion
    )
    AS BEGIN 
      DECLARE @r int;
      DECLARE @key varchar(10);
      BEGIN TRY
        UPDATE [dbo].[tabella]
        	SET ... = ...,
        	WHERE [Id] = @Id
        	   AND [ColRowVersion] = @RowVersion;
        
        SET @r = @@ROWCOUNT;
      
        IF (@r = 0) BEGIN			
          -- in caso di non aggiornamento righe notifica
          -- la possibile violazione di concorreza
          SELECT @msg = 'Impossibile aggiornare riga con Codice = [%s] in  [%s].' + CHAR(10) + 'Possibile conflitto di concorrenza.',
            @key = CONVERT(varchar(10), @Id); 
    
          RAISERROR (@msg, 16, 1, @Key , 'tabella xyz');
          END;
      
        RETURN 0;  
      END TRY
      
      BEGIN CATCH
        -- ritorna l'errore
        DECLARE @ErrorMSG varchar(2000);
        SET @ErrorMSG = ERROR_MESSAGE();
        RAISERROR (@ErrorMSG, 16, 1);
        RETURN -100;
      END CATCH
    END;

    questo per non verificare a livello di ogni singola colonna che il nostro aggiornamento collida con aggiornamenti parziali effettuati da altri nel caso si richieda, appunto, un lock pessimistico completo...

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    • Contrassegnato come risposta Mancini, mercoledì 31 ottobre 2012 22:07
    martedì 30 ottobre 2012 11:39
    Moderatore
  • Come al solito chiarissimo

    _______ Grazie

    .

    mercoledì 31 ottobre 2012 22:11