17

estoy tratando de escribir esta consulta para encontrar todas las mesas con columna específica con algún valor específico. Esto es lo que he hecho hasta ahora -el uso de SQL Server sp_msforeachtable para seleccionar sólo las tablas que cumplen alguna condición

EXEC sp_MSforeachtable 
@command1=' 
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE") 
BEGIN 
    IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0 
    BEGIN 
     SELECT * FROM ? WHERE EMP_CODE="HO081" 
    END 
END 
' 

espero que mis intenciones son claras, sólo quiero para seleccionar sólo las tablas, donde está presente y en esas tablas de la columna EMP_CODE Quiero seleccionar aquellas filas donde EMP_CODE='HO081' .

Editar -

Ahora se destaca como este. Pero no puedo reemplazar la variable @EMPCODE en la consulta.

DECLARE @EMPCODE AS VARCHAR(20) 
SET @EMPCODE='HO081' 
EXEC sp_MSforeachtable 
@command1=' 
    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 
',@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME='''[email protected]+''')' 

Respuesta

45

Usted sabe cómo es indocumentado sp_MSforeachtable, y puede desaparecer en cualquier momento/modificar?

Bueno, si estás dispuesto a hacer caso omiso de eso, tiene otro parámetro llamado @whereand, que se adjunta a la WHERE cláusula de la consulta interna que se utiliza para encontrar las tablas (y debe comenzar con una AND).

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

uso de este conocimiento, es posible que las embarcaciones de su parámetro @whereand 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 usted sabe que sólo se ejecuta en las tablas que contienen una columna EMP_CODE. Probablemente también sacara la condición COUNT(*), ya que no veo qué valor está agregando.


actualizada en base a su trabajo adicional, y comprueba frente a una mesa:

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 los @whereand para consultar EMP_CODE, ya que no desea reemplazar el valor que hay)

La cuestión es que, puede pasar parámetros a un procedimiento almacenado, o literales, pero no se puede realizar cálculos/la combinación de acciones entre ellos - así que moví la construcción de la instrucción SQL a cabo en una acción separada.

+4

+1 para mostrar lo que se puede hacer, pero de manera implícita que le dice que no lo haga;?) – cairnz

+0

@Damien_The_Unbeliever Supongamos que si escribo 'SI (SELECT COUNT (*), desde donde EMP_CODE = '' '+ @EMPCODE + '' ')> 0' entonces ¿por qué me está dando - sintaxis incorrecta cerca de '+'. Estoy tratando de pasar el valor 'EMP_CODE' a través de una variable. –

+0

@SohamDasgupta - Es un poco difícil diagnosticar este tipo de problema en la sección de comentarios, ya que realmente necesitaría ver toda la consulta tal como está ahora, y eso no va a funcionar en los comentarios. Sin embargo, volvería a consultar ese fragmento de código en particular: ¿por qué * contar * el número de filas coincidentes en lugar de simplemente seleccionarlas? Los conjuntos de resultados vacíos suelen ser bastante fáciles de tratar. –

9

Supongo que se produce un error de algún tipo, quizás Invalid column name 'EMP_CODE'?

Se debe a que el código se compiló antes de verificar la columna. Puede hacer esto en su lugar.

EXEC sp_MSforeachtable 
@command1=' 
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=PARSENAME("?",2) AND TABLE_NAME=PARSENAME("?",1) AND COLUMN_NAME="EMP_CODE") 
BEGIN 
    EXEC('' 
      IF (SELECT COUNT(*) FROM ? WHERE EMP_CODE="HO081")>0 
      BEGIN 
       SELECT * FROM ? WHERE EMP_CODE="HO081" 
      END 
     '') 
END 
' 
+0

Funciona muy bien. Gracias. –

Cuestiones relacionadas