Uno dei miei campi DB NON È NULL?
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
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