Newsgroup: it.comp.appl.access
Titolo: Query per restituire i nomi dei campi mai usati su una certa tabella

Access 2013 che invia query passtrough verso Sql Server
Non funziona come mi attendo, nel senso che pur non segnalando nessun 
errore, non restituisce nessuna riga
Provo via Sql Manager e pure allui niente errori e nessuna riga di ritorno
Quindi e' evidentemente una query difettosa per la quale ho bisogno del 
vostro prezioso aiuto
 
------------------------
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'ART_ANA'
AND COLUMN_NAME NOT IN
(SELECT COLUMN_NAME FROM db1.dbo.ART_ANA WHERE COLUMN_NAME IS NOT NULL)
------------------------
 
L'intento e' quello di avere una lista dei campi mai utilizzati per una 
certa tabella indicata (nell'esempio sopra ART_ANA), campi che 
contengono solamente null in tutte le eventuali righe presenti nella tabella
E quindi mi attenderei che almeno una riga con CAMPO1 venisse restituita
 
Ho verificato che la tabella sia abile a restituire almeno qualche 
campo, sia visivamente scorrendo alcune colonne da inizio a fine ed 
accertandomi che appaia in giallino solamente il campo null, sia via
 
select * from db1.dbo.ART_ANA where CAMPO1 is null
select * from db1.dbo.ART_ANA where CAMPO1 <> null
 
E nel primo caso mi vengono restituite tutte le righe tabella
Nel secondo caso nessuna riga viene restituita
Quindi sono fiducioso che i dati nella tabella contangano almeno CAMPO1 
che non e' mai stato valorizzato su nessuna riga
 
E quindi resta solamente la query malformata
Che dite?  Che c'ha di sbagliato la query sopra?


Ciao Roberto,
la query rende il risultato corretto ovvero nessun record, il campo COLUMN_NAME della subquery è riferito alla query principale, in pratica è come se tu vai a scrivere :
--------------------------------------
SELECT 'Campo1' as COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'ART_ANA'
AND 'Campo1' NOT IN
(SELECT 'Campo1' FROM db1.dbo.ART_ANA WHERE 'Campo1' IS NOT NULL)
--------------------------------------
 
non c'è modo di ottenere quello che vuoi senza ricorrere all'Sql dinamico, una possibile soluzione potrebbe essere questa:
--------------------------------------
set nocount on;
declare @Sql nvarchar(max)='',
              @NomeTabella nvarchar(128) = 'ART_ANA',
              @NomeSchema  nvarchar(128) = 'dbo';
 
select @Sql = @Sql + ',Count([' + COLUMN_NAME + ']) as ['+ COLUMN_NAME +']'
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME = @NomeTabella
  and TABLE_SCHEMA = @NomeSchema;
 
select @Sql = @Sql + ' FROM ' + @NomeSchema+'.'+@NomeTabella;
select @Sql='SELECT ' + Stuff(@Sql,1,1,'');
 
exec (@Sql);
--------------------------------------
ti verrà restituita una sola riga con tutti i campi e sotto di essi il conteggio dei record, dove il conteggio è uguale a 0 significa che in tutte le righe della tabella quel campo è NULL.
Forse il risultato non è comodo da leggere ma al momento questa è la soluzione più semplice che mi è venuta in mente.
 
Ciao
Giorgio Rancati
 
 


Si certo, il funzionamento della query e' quiaro
scusate ma non ho resistito  :)
Ma come mai non viene restituito nessun record?
La subquery quando, COLUMN_NAME assume il nome CAMPO1, dovrebbe 
restituire un insieme vuoto, e credo lo faccia
E di conseguenza la NOT IN dovrebbe restituire il contenuto corrente del 
COLUM_NAME che e' CAMPO1
Come mai non lo fa?
Qualcosa non e' ben chiaro quando entra in gioco il null


Ciao Roberto,
quando COLUMN_NAME assume il valore 'Campo1'  la subquery diventa:
----
SELECT 'Campo1' FROM db1.dbo.ART_ANA WHERE 'Campo1' IS NOT NULL
----
prova ad eseguirla, restituirà tante righe quante quelle presenti in tabella e tutte con il solo campo (nessun nome di colonna) valorizzato a 'Campo1'
 
Ciao
Giorgio Rancati


quello che a te servirebbe è qualcosa come:
----
SELECT Fields('Campo1') FROM db1.dbo.ART_ANA WHERE Fields('Campo1') IS NOT NULL
che implementata nella tua queri diventerebbe
SELECT Fields(COLUMN_NAME) FROM db1.dbo.ART_ANA WHERE Fields(COLUMN_NAME) IS NOT NULL
----
ma in Sql server questa cosa non esiste
 
Ciao
Giorgio Rancati
 


No, forse ti confondi, con 'is not null' come condizione la subquery 
restituisce nessuna riga, ed e' corretto essendo che su quella colonna 
ci sono solo null
Prova ne sia che se sulla stessa subquery gli do 'is null' cosi:
SELECT 'Campo1' FROM db1.dbo.ART_ANA WHERE 'Campo1' IS NULL
restituisce tanti record quanti sono presenti nella tabella, nel mio 
caso 16.314
 
Detto questo, rimane la curiosita' di capire come mai quel NOT IN se gli 
passi un subset vuoto di record (la subquery), non restituisca il nome 
del campo (il contenuto di COLUMNAME e quindi il nome del campo corrente)


.
prova ad eseguire
----
SELECT 'Campo1' FROM db1.dbo.ART_ANA WHERE 'Campo1' IS NOT NULL
----
la costante 'Campo1' non è NULL  ha valore testuale Campo1, non confondere la costante 'Campo1' con l'effettivo Campo1
 
Giorgio Rancati
 
 


Si hai ragione, usando l'esempio che hai scritto tu:
SELECT 'Campo1' FROM db1.dbo.ART_ANA WHERE 'Campo1' IS NOT NULL
vengono restituite tutte le righe tabella, ovviamente, poiche' la 
costante 'campo1' e' sempre diversa da null
 
Mi riferivo pero' alla subquery:
(SELECT COLUMN_NAME FROM db1.dbo.ART_ANA WHERE COLUMN_NAME IS NOT NULL)
in questo caso COLUMN_NAME dovrebbe essere sostituita dal nome del campo 
corrente, come preso dalla riga della query rincipale, e quindi 
supponendo che la tabella ART_ANA sia composta dai campi:
 
codice
descrizione
Campo1
prezzo
 
quando la query principale restituisce Campo1 (alla terza riga 
restituita), la subquery dovrebbe diventare equivalente a:
(SELECT Campo1 FROM db1.dbo.ART_ANA WHERE Campo1 IS NOT NULL)
che restituisce zero righe, e quindi la query complessiva dovrebbe 
restituire almeno una riga contenente il nome Campo1
 
COLUMN_NAME non e' una costante, dovrebbe assumere di volta in volta il 
nome di uno dei campi costituenti la tabella
Perche' dici  "LA COSTANTE" 'Campo1' ?
 


Ciao,
COLUMN_NAME per la subquery è una costante contenente il valore testuale del nome campo.
 
faccio un'analogia con VBA
----------------------
    Dim Campo1 As String
    Dim Campo2 As String
 
    Dim NomeCampo As String
 
    Campo1 = "Access"
    Campo2 = "Sql Server"
 
    NomeCampo = "Campo1"
 
    Debug.Print NomeCampo
------------------
 
ovviamente nella finestra immediata verrà stampato il valore testuale (Campo1) e non il valore contenuto della variabile Campo1 (Access), la stessa cosa succede per la query che che hai scritto.
 
Ciao
Giorgio Rancati


precisazione:
COLUMN_NAME per la subquery è una costante che assume di volta in volta il valore testuale del nome campo.