2010-10-04 14 views
6

Mam instrukcję select, która zwraca tabelę pełną instrukcji SELECT (Przechodzi przez każdą kolumnę w każdej tabeli i tworzy zaznaczenie, aby znaleźć, czy ta kolumna zawiera jakiekolwiek błędne dane) .Tabela z wybranymi instrukcjami, wykonywanie dynamicznego SQL i powracającymi wartościami

Muszę wziąć tę tabelę pełną instrukcji SELECT, wykonać je i sprawdzić, czy któryś z nich zwraca wiersze. Jeśli liczba (*)> 0, chcę wydrukować niektóre dane.

Myślałem, że muszę użyć kursora, ale nie mam pojęcia, jak to osiągnąć.

Oto mój kod, aby uzyskać liczbę złych danych.

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 

ta zwraca tabelę z wierszy jak:

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

muszę wykonać to select, a jeśli count (*)> 0, a następnie wydrukować drugą kolumnę. Nie chcę pokazywać niczego w wynikach lub wiadomościach, chyba że są dane do pokazania.

+0

która wersja serwera SQL Używasz ? –

+1

czy moja ostatnia edycja zrobiła to, czego potrzebujesz? –

+0

2005 ... (11 kolejnych znaków) – Martin

Odpowiedz

3

spróbuj tego:

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

Mogę po prostu skopiować i wkleić wszystkie instrukcje wyboru z tabeli i uzyskać to ... – Martin

+0

'Muszę wziąć tę tabelę pełną instrukcji SELECT, wykonać je" czy to nie to, co wam dałem? –

+2

@KM, wygodnie pominąłeś resztę tego cytatu. Pozwól, że skończę dla ciebie: '... i zobacz, czy któryś z nich zwraca wiersze. Jeśli liczba (*)> 0, chcę wydrukować niektóre dane. Czy masz jakąkolwiek szansę na pracę dla Fox News? –

0

Po pierwsze, chciałbym zmienić ciąg SQL budujesz nieznacznie się

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

Byłoby to ci łańcuch, gdy warunek jest spełniony i NULL, gdy tak nie jest.

chodzi o mechanikę kursorem samego:

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

Po pierwsze - sp_executesql pobiera ntext/nchar/nvarchar ... 2) To po prostu wypisuje mnóstwo tabel z NULLS. Mógłbym po prostu dokonać wyboru stołu i uzyskać te same wyniki. – Martin

+0

@Martin: 1. Dzięki za połów na nvarchar. Wiedziałem lepiej, ale czasami moje palce i mózg się rozłączają. 2. Zmodyfikowalem moją odpowiedź, aby przechowywać wyniki w tabeli tymczasowej, którą można zapytać na końcu, eliminując w ten sposób wyniki NULL. –

0

sp_executesql może zaakceptować parametry wyjściowe:

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; 
Powiązane problemy