sql >> Base de Datos >  >> RDS >> Sqlserver

Uso de SQL Server sp_msforeachtable para seleccionar solo aquellas tablas que cumplen alguna condición

Ya sabes cómo sp_MSforeachtable no está documentado y puede desaparecer en cualquier momento o modificarse?

Bueno, si está feliz de ignorar eso, tiene otro parámetro llamado @whereand , que se adjunta al WHERE cláusula de la consulta interna que se utiliza para encontrar las tablas (y debe comenzar con un AND ).

También tienes que saber que hay un alias, o contra sysobjects y un segundo alias syso contra sys.all_objects .

Con este conocimiento, puede crear su @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'')'

Ahora también puede simplificar su command1 , ya que sabe que solo se ejecutará en tablas que contengan un EMP_CODE columna. Probablemente eliminaría el COUNT(*) condición también, ya que no veo qué valor está agregando.

Actualizado en función de su trabajo posterior y probado en una tabla:

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'')'

(He revertido el @whereand para consultar por EMP_CODE , ya que no desea reemplazar el valor allí).

El problema es que puede pasar parámetros a un procedimiento almacenado, o literales , pero no puede realizar cálculos/combinar acciones entre ellos, así que moví la construcción de la instrucción sql a una acción separada.