2012-04-05 1 views
6

Utilizzando la stored procedure sp_msforeachtable è possibile eseguire uno script per tutte le tabelle in un database.Come verificare se le tabelle di SQL Server sono tabelle di sistema

Tuttavia, ci sono tabelle di sistema che vorrei escludere da ciò. Istintivamente, controllerei le proprietà IsSystemTable o IsMSShipped. Questi non funzionare come mi aspetto - ho per esempio una tabella chiamata __RefactorLog:

System table

Ma quando interrogo se questo è un sistema o MS tavolo Spedito, SQL Server segnala nessuno dei miei tavoli sono sistema tabelle:

exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsSystemTable'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser' 
-- Results of IsSystemTable: 
[dbo].[__RefactorLog] = 0 
[schema].[myUserTable] = 0 

e

exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsMSShipped'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser' 

-- Results of IsMSShipped: 
[dbo].[__RefactorLog] = 0 
[schema].[myUserTable] = 0 

Quando guardo nelle proprietà della tabella (interno SSMS), la tabella è contrassegnato come sy oggetto staminale. Tuttavia una proprietà dell'oggetto come IsSystemObject non esiste (AFAIK).

Come si verifica se una tabella è un oggetto di sistema, a parte la proprietà dell'oggetto? In che modo SSMS verifica se una tabella è un oggetto di sistema?

+0

Sebbene questa domanda sembri http://stackoverflow.com/questions/3216219/get-list-of-tables-but-not-include-system-tables-sql-server-2k, non è duplicata come i modi di controllare le proprietà dell'oggetto sono cambiati da SQL Server 2000 e sto chiedendo il modo in cui SSMS lo controlla. – vstrien

+0

È sempre possibile eseguire il profiler di SQL Server sul server quando si apre la cartella "Tabelle di sistema" e vedere quale SQL è in esecuzione. –

risposta

8

Management Studio 2008 sembra eseguire del codice abbastanza brutto seguente quando si aprono le "Tabelle di sistema" cartella in Esplora oggetti, il bit chiave sembra essere:

CAST(
case 
    when tbl.is_ms_shipped = 1 then 1 
    when (
     select 
      major_id 
     from 
      sys.extended_properties 
     where 
      major_id = tbl.object_id and 
      minor_id = 0 and 
      class = 1 and 
      name = N''microsoft_database_tools_support'') 
     is not null then 1 
    else 0 
end   
      AS bit) AS [IsSystemObject] 

(Dove tbl è un alias per sys.tables

Quindi sembra che sia una combinazione - is_ms_shipped da sys.tables a 1 o con un set di proprietà esteso particolare.

1

In passato ho lavorato sul presupposto che, nella tabella sys.objects, la colonna is_ms_shipped indica se un oggetto è o non è un oggetto di sistema. (Questa colonna viene ereditata da altre tabelle di sistema, come sys.tables.)

Questo flag può essere impostato dalla procedura sp_ms_markSystemObject. Questa, tuttavia, è una procedura non documentata, non è supportata da Microsoft, non penso che dovremmo saperlo, quindi non te ne ho parlato.

0

Mi manca qualcosa?

Tuttavia, ci sono tabelle di sistema che mi piacerebbe di escludere da quella

Almeno in SQL Server 2008, sp_MSforeachtablegià tabelle di sistema esclude, come questo estratto da esso mostra:

+ N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + @mscat + N' = 0 ' 
+0

Non so se ti manca qualcosa, ma quando eseguo le query specificate mentre sei loggato come mio utente ETL, la query tenta anche di elaborare la tabella __RefactorLog (che SSMS designa come 'oggetto di sistema') – vstrien

+2

Una volta in un momento, mi sono imbattuto nel fatto che Enterprise Manager (SQL 2000) era codificato per trattare alcune tabelle come tabelle di sistema, sebbene SQL stesso non le contrassegnasse come tali. (Questa era la tabella dei diagrammi.) Potrebbero ancora fare trucchi come questo in SSMS ... –

1

__refactorlog è, a differenza di quanto suggerisce SSMS, una tabella utente. Viene utilizzato durante la distribuzione per tenere traccia delle modifiche dello schema che non possono essere dedotte dallo stato attuale del database, ad esempio rinominare una tabella.

Se tutte le altre tabelle utente sono in uno schema personalizzato (non-dbo), è possibile utilizzare una combinazione degli attributi isMSshipped/isSystemTable e il nome dello schema per decidere se una tabella è "in ambito" per il proprio script.