2010-10-04 4 views
6

Ho un'istruzione select che restituisce una tabella completa di istruzioni SELECT (attraversa ogni colonna in ogni tabella e crea una selezione per trovare se quella colonna contiene dati non validi) .Tabella con istruzioni Select, esecuzione di SQL dinamico e valori restituiti

Ho bisogno di prendere questa tabella piena di istruzioni SELECT, eseguirle e vedere se qualcuno di loro restituisce righe. Se il conteggio (*)> 0, allora voglio stampare alcuni dati.

Stavo pensando di dover usare un cursore, ma non ho idea di come realizzarlo.

Ecco il mio codice per ottenere il conteggio dei dati errati.

SELECT 'SELECT count(*), '' '+sysobjects.name + ' - ' + syscolumns.name + 
    ' '' FROM [' 
     +sysobjects.name + '] WHERE UNICODE(SUBSTRING(['+syscolumns.name+'],Len(['+syscolumns.name+']),1)) = 0' 
     FROM sysobjects 
    JOIN syscolumns ON sysobjects.id = syscolumns.id 
    JOIN systypes ON syscolumns.xtype=systypes.xtype 
    WHERE sysobjects.xtype='U' and systypes.name IN ('varchar', 'nvarchar') 
ORDER BY sysobjects.name,syscolumns.colid 

Questo restituisce una tabella con righe come:

SELECT count(*), ' All_MW_Users - LastName ' FROM [All_MW_Users] WHERE UNICODE(SUBSTRING([LastName],Len([LastName]),1)) = 0 

ho bisogno di eseguire questo selezionare, e se il conteggio (*)> 0, quindi stampare la seconda colonna. Non voglio mostrare nulla nei risultati o nei messaggi a meno che non ci siano dati da mostrare.

+0

la versione di SQL Server si usa ? –

+1

la mia ultima modifica ha fatto ciò di cui hai bisogno? –

+0

2005 ... (11 caratteri in più) – Martin

risposta

3

provare questo:

DECLARE @SQL nvarchar(max) 
SET @SQL='DECLARE @TempTable table (RowID int identity(1,1), CountOf int, DescriptionOf nvarchar(500));' 
SELECT @[email protected]+';INSERT @TempTable (CountOf,DescriptionOf) SELECT count(*), '' '+sysobjects.name + ' - ' + syscolumns.name + 
    ' '' FROM [' 
     +sysobjects.name + '] WHERE UNICODE(SUBSTRING(['+syscolumns.name+'],Len(['+syscolumns.name+']),1)) = 0' 
     FROM sysobjects 
    JOIN syscolumns ON sysobjects.id = syscolumns.id 
    JOIN systypes ON syscolumns.xtype=systypes.xtype 
    WHERE sysobjects.xtype='U' and systypes.name IN ('varchar', 'nvarchar') 
ORDER BY sysobjects.name,syscolumns.colid 

SET @[email protected]+';SELECT * FROM @TempTable WHERE CountOF>0' --make sure there is no truncation of the commands 

EXEC (@SQL) 
+0

Potrei semplicemente copiare e incollare tutte le istruzioni select dalla tabella e ottenere questo ... – Martin

+0

'Ho bisogno di prendere questa tabella piena di istruzioni SELECT, eseguirle' non è quello che ti ho dato? –

+2

@ KM, hai lasciato il resto di quella citazione. Permettetemi di finirlo per voi: '... e vedere se qualcuno di loro restituisce righe. Se il conteggio (*)> 0, allora voglio stampare alcuni dati. Qualche possibilità che lavori per Fox News? –

0

In primo luogo, vorrei cambiare la stringa SQL si sta costruendo un po 'di essere

SELECT CASE WHEN count(*)>0 THEN ' All_MW_Users - LastName ' END FROM [All_MW_Users] WHERE UNICODE(SUBSTRING([LastName],Len([LastName]),1)) = 0 

Questo si otterrebbe la stringa quando la condizione è soddisfatta e NULL quando non lo è.

Per quanto riguarda la meccanica del cursore stesso:

declare @SQLSTring nvarchar(4000) 

create table #tmpResults (
    OutputString nvarchar(1000) 
) 

declare DynamicSQL cursor for 
    {The Select Statement in your question with modification} 

open DynamicSQL 

while (1=1) begin 
    fetch next from DynamicSQL 
     into @SQLString 

    if @@fetch_status <> 0 
     break; 

    insert into #tmpResults 
     (OutputString) 
     exec sp_executesql @SQLString 
end /* while */ 

close DynamicSQL 
deallocate DynamicSQL 

select OutputString 
    from #tmpResults 
    where OutputString is not null 
+0

Prima di tutto - sp_executesql accetta ntext/nchar/nvarchar ... 2) Questo stampa solo una tonnellata di tabelle con NULLS. Potrei semplicemente fare una selezione del tavolo e ottenere gli stessi risultati – Martin

+0

@ Martin: 1. Grazie per la presa sul nvarchar. Lo sapevo meglio, ma a volte le mie dita e il mio cervello si disconnettono. 2. Ho modificato la mia risposta per memorizzare i risultati in una tabella temporanea che è possibile interrogare alla fine, eliminando così i risultati NULL. –

0

sp_executesql può accettare parametri di uscita:

declare c cursor static forward_only read_only for 
SELECT N'SELECT @count = count(*)' + 
    N' FROM ' + quotename(s.name) + '.' + quotename(t.name) + 
    N' WHERE UNICODE(SUBSTRING(' + quotename(c.name) + N', len('+ quotename(c.name) + N'),1)) = 0x00' 
    , s.name as schema_name 
    , t.name as table_name 
    , c.name as column_name 
    from sys.tables t 
    join sys.schemas s on t.schema_id = s.schema_id 
    join sys.columns c on t.object_id = c.object_id 
    join sys.types x on c.user_type_id = x.user_type_id 
    where x.name in (N'varchar', N'nvarchar'); 

open c; 

declare @sql nvarchar(max), @s sysname, @t sysname, @c sysname; 
fetch next from c into @sql, @s, @t, @c; 
while 0 = @@fetch_status 
begin 
    declare @count bigint = 0; 
    print @sql; 
    exec sp_executesql @sql, N'@count bigint output', @count output; 
    raiserror (N'%s.%s.%s: %I64d', 0,1, @s, @t, @c, @count); 
       -- if @count is not 0, act here 
    fetch next from c into @sql, @s, @t, @c; 
end 

close c; 
deallocate c; 
Problemi correlati