Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Uso do SQL Server sp_msforeachtable para selecionar apenas as tabelas que atendem a alguma condição


Você sabe como sp_MSforeachtable não está documentado e pode desaparecer a qualquer momento/ser modificado?

Bem, se você está feliz em ignorar isso, ele tem outro parâmetro chamado @whereand , que é anexado ao WHERE cláusula da consulta interna que está sendo usada para encontrar as tabelas (e deve começar com um AND ).

Você também precisa saber que existe um alias, o contra sysobjects , e um segundo alias syso em relação a sys.all_objects .

Usando esse conhecimento, você pode criar seu @whereand parâmetro como:
EXEC sp_MSforeachtable 
@command1='...',
@whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')'

Agora você também pode simplificar seu command1 , já que você sabe que ele só será executado em tabelas contendo um EMP_CODE coluna. Eu provavelmente tiraria o COUNT(*) condição também, já que não vejo qual valor está agregando.

Atualizado com base em seu trabalho adicional e testado em uma tabela:
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'')'

(Eu reverti o @whereand para consultar EMP_CODE , já que você não deseja substituir o valor lá).

O problema é que você pode passar parâmetros para um procedimento armazenado ou literais , mas você não pode realizar cálculos/combinar ações entre eles - então mudei a construção da instrução sql para uma ação separada.