Domanda

Devo occuparmi di una tabella in cui vi è una serie di campi ciascuno seguito da un secondo campo che conterrà un nuovo valore suggerito fino a quando questa modifica non sarà confermata.

Sembra un po 'così:

refID    field1    newField1    field2    newField2   ... 

refID è un valore ID collegato a una tabella principale. Una riga nella tabella principale può contenere n righe nella mia tabella dei dettagli. I tipi di dati includono ints, stringhe e dateTimes.

Ora sto cercando una query che mi dica, dato un refID, se ci sono delle modifiche suggerite nella tabella dei dettagli.

Stavo giocando un po 'con alcune selezioni UNION, con COALESCE () e ISNULL () ... ma tutti questi tentativi sembravano alquanto strani. Il DB è MS-SQL-Server 2005.

Per chiarire il mio problema:

--this is a simplification of the details table in question
CREATE TABLE [dbo].[TEST_TABLE](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [refID] [int] NOT NULL,
    [firstName] [varchar](50) NULL,
    [newFirstName] [varchar](50) NULL,
    [lastName] [varchar](50) NULL,
    [newLastName] [varchar](50) NULL
)

--here we insert a detail row ... one of many that might exist for the master table (e.g. data about the company)
insert into TEST_TABLE(refID, firstName, lastName) values(666, 'Bill', 'Ballmer')
--this is what happens when a user saves a suggested change
update TEST_TABLE SET newLastName = 'Gates' where ID = 1
--and this is what happens when this suggestion is accepted by a second user
update TEST_TABLE set lastName=newLastName, newLastName = NULL where ID = 1
È stato utile?

Soluzione

Questa è la soluzione più pulita che mi viene in mente dalla cima della mia testa. Dovresti ripetere la logica per ogni elemento di dati (col1, col2, ecc.):

DECLARE @RefID int, @Changes bit

SET @Changes = 0 --No changes by default

SET @RefID = 42 --Your RefID

IF EXISTS(SELECT * FROM MyDetailTable
          WHERE RefID = @RefID
          AND (
          (Col1 IS NULL AND NewCol1 IS NOT NULL)
          OR 
          (Col1 IS NOT NULL AND NewCol1 IS NULL)
          OR
          (Col1 <> Col2)
          ))
   SET @Changes = 1

Altri suggerimenti

Ho modificato la soluzione di randolphos.

 select 
        refID ,
        case when 
            newField1 is not null or
            newField2 is not null or
            ...
        then 1 else 0 end  haschanged
    from myTable
    where refID = @refID

Aggiornamento: sostanzialmente ciò che ha detto Aron Aalton in un altro formato di output.

Ecco una semplice query:

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE COALESCE(t.newFirstName,t.newLastName) IS NOT NULL
       AND t.refID = 1

Questa query restituirà una singola riga se ci sono modifiche proposte per un dato refID (basato sull'esempio nella tua domanda.)

Per la tua tabella, ovviamente, dovresti elencare ciascuna delle colonne 'newValue' come argomenti nella funzione COALESCE. (Nell'elenco di coalescenza, raccomando espressamente di trasmettere qualsiasi non-VARCHAR a VARCHAR, solo per chiarire che ogni espressione nell'elenco è dello stesso tipo di dati.

Se preferisci usare un'espressione CASE piuttosto che COALESCE:

    SELECT TOP 1 1 as found
      FROM [dbo].[TEST_TABLE] t
     WHERE CASE 
           WHEN t.newFirstName IS NOT NULL THEN 1
           WHEN t.newLastName  IS NOT NULL THEN 1
           ELSE NULL
           END IS NOT NULL
       AND t.refID = 1

Questo schema è già definito e in produzione? In caso contrario, consiglierei vivamente di avere una tabella 'modifiche' separata con qualche descrizione - forse usare fieldname, fieldvalue dove fieldvalue è un sql_variant.

Non credo che la tua struttura esistente sembrerà bella quando i valori saranno "accettati" (presumo nulla) soprattutto perché non manterrai alcuna cronologia di audit con questo approccio.

Non posso provarlo, ma forse:

select (field1 is not null and field2 is not null) as ChangesMade where refID = @id
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top