Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Utilizzo di SQL Server sp_msforeachtable per selezionare solo le tabelle che soddisfano alcune condizioni

Sai come sp_MSforeachtable non è documentato e può scomparire in qualsiasi momento/essere modificato?

Bene, se sei felice di ignorarlo, ha un altro parametro chiamato @whereand , che viene aggiunto a WHERE clausola della query interna utilizzata per trovare le tabelle (e dovrebbe iniziare con un AND ).

Devi anche sapere che c'è un alias, o contro sysobjects e un secondo alias syso contro sys.all_objects .

Usando questa conoscenza, potresti creare il tuo @whereand parametro come:

EXEC sp_MSforeachtable 
@command1='...',
@whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')'

Ora puoi anche semplificare il tuo command1 , poiché sai che verrà eseguito solo su tabelle contenenti un EMP_CODE colonna. Probabilmente eliminerei il COUNT(*) condizione anche, dal momento che non vedo quale valore sta aggiungendo.

Aggiornato in base al tuo ulteriore lavoro e testato su una tabella:

DECLARE @EMPCODE AS VARCHAR(20)
SET @EMPCODE='HO081'
declare @sql nvarchar(2000)
set @sql = '
    DECLARE @COUNT AS INT
    SELECT @COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''[email protected]+'''
    IF @COUNT>0
    BEGIN
        PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,@COUNT)+'' ROW(S)''
        --PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''[email protected]+'''''''
    END
'
EXEC sp_MSforeachtable 
@[email protected],@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME=''EMP_CODE'')'

(Ho ripristinato il @whereand per interrogare EMP_CODE , poiché non vuoi sostituire il valore lì).

Il problema è che puoi passare parametri a una procedura memorizzata, o letterali , ma non puoi eseguire calcoli/combinare azioni tra di loro, quindi ho spostato la costruzione dell'istruzione sql in un'azione separata.