2010-10-04 5 views
6

Ich habe eine Select-Anweisung, die eine Tabelle mit SELECT-Anweisungen zurückgibt (Sie durchläuft jede Spalte in jeder Tabelle und erstellt eine Auswahl, um festzustellen, ob diese Spalte ungültige Daten enthält) .Tabelle mit Select-Anweisungen, Ausführen von Dynamic SQL und Rückgabe von Werten

Ich muss diese Tabelle voll von SELECT-Anweisungen nehmen, sie ausführen und sehen, ob einige von ihnen Zeilen zurückgeben. Wenn die Anzahl (*)> 0 ist, dann möchte ich einige Daten ausdrucken.

Ich dachte, ich müsste einen Cursor verwenden, aber ich habe keine Ahnung, wie ich das erreichen würde.

Hier ist mein Code, um die Anzahl der schlechten Daten zu erhalten.

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 

Dies gibt eine Tabelle mit Zeilen wie:

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

ich diese wählen Sie ausführen müssen, und wenn der COUNT (*)> 0, dann die zweite Spalte drucken. Ich möchte nichts in den Ergebnissen oder Nachrichten anzeigen, wenn keine Daten angezeigt werden.

+0

die Version von SQL Server verwenden Sie, ? –

+1

hat meine letzte Bearbeitung getan, was Sie brauchen? –

+0

2005 ... (11 weitere Zeichen zu gehen) – Martin

Antwort

3

try this:

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

Ich könnte nur kopieren und fügen Sie alle Select-Anweisungen aus der Tabelle und bekommen Sie diese ... – Martin

+0

'Ich muss diese Tabelle voll von SELECT-Anweisungen nehmen, sie auszuführen" ist das nicht, was ich dir gegeben habe? –

+2

@KM, haben Sie bequem den Rest dieses Zitats weggelassen. Gestatten Sie mir, es für Sie zu beenden: '... und sehen Sie, ob einige von ihnen in die Reihen zurückkehren. Wenn die Zählung (*)> 0 ist, dann möchte ich einige Daten ausdrucken. Gibt es eine Chance für Fox News? –

0

Zuerst würde ich die SQL-Zeichenfolge ändern Sie bauen leicht

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

sein Dieser würden Sie die Zeichenfolge erhalten, wenn die Bedingung erfüllt ist und NULL, wenn es nicht ist.

Was die Mechanik des Cursors selbst:

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

Zuerst off - sp_executesql dauert ntext/nchar/nvarchar ... 2) Dies druckt nur eine Tonne von Tabellen mit NULLEN. Ich könnte nur eine Auswahl der Tabelle tun und die gleichen Ergebnisse – Martin

+0

@Martin bekommen: 1. Danke für den Fang auf dem Nvarchar. Ich wusste es besser, aber meine Finger und mein Gehirn trennen sich manchmal. 2. Ich habe meine Antwort geändert, um die Ergebnisse in einer temporären Tabelle zu speichern, die Sie am Ende abfragen können, wodurch die NULL-Ergebnisse eliminiert werden. –

0

Sp_executesql Ausgangsparameter annehmen können:

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;