SQL Server sp_msforeachtable用法只select那些满足某些条件的表
我正在试图写这个查询来查找具有特定值的特定列的所有表。 这是我迄今为止所做的 –
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 '  我希望我的内涵很清楚,我只想selectEMP_CODE列所在的那些表,在这些表中我想select那些EMP_CODE='HO081' 。 
编辑 –
 现在它是这样的。 但是我不能在查询中replace@EMPCODEvariables。 
 DECLARE @EMPCODE AS VARCHAR(20) SET @EMPCODE='HO081' EXEC sp_MSforeachtable @command1=' DECLARE @COUNT AS INT SELECT @COUNT=COUNT(*) FROM ? WHERE EMP_CODE='''+@EMPCODE+''' IF @COUNT>0 BEGIN PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,@COUNT)+'' ROW(S)'' --PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''+@EMPCODE+''''''' END ',@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME='''+@EMPCODE+''')' 
	
 你知道sp_MSforeachtable是如何没有logging的,并可能在任何时候离开/被修改? 
 那么,如果你很高兴忽略它,它有另一个名为@whereand参数,它被附加到正在用来查找表的内部查询的WHERE子句(并且应该以AND开头)。 
 你还必须知道有一个别名, o对sysobjects ,和第二syso名syso对sys.all_objects 。 
 使用这些知识,你可以制作你的@whereand参数: 
 EXEC sp_MSforeachtable @command1='...', @whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')' 
 您现在也可以简化您的command1 ,因为您知道它只能在包含EMP_CODE列的表上运行。 我可能会拿出COUNT(*)条件,因为我没有看到它增加了什么价值。 
根据您的进一步工作进行更新,并针对一张表进行testing:
 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='''+@EMPCODE+''' IF @COUNT>0 BEGIN PRINT PARSENAME("?",1)+'' => ''+CONVERT(VARCHAR,@COUNT)+'' ROW(S)'' --PRINT ''DELETE FROM ''+PARSENAME("?",1)+'' WHERE EMP_CODE='''''+@EMPCODE+''''''' END ' EXEC sp_MSforeachtable @command1=@sql,@whereand='AND O.ID IN (SELECT OBJECT_ID FROM SYS.COLUMNS C WHERE C.NAME=''EMP_CODE'')' 
  (我已经恢复@whereand和查询EMP_CODE ,因为你不想在那里取代值)。 
问题是,你可以将参数传递给存储过程或文字 ,但不能在它们之间执行计算/组合操作 – 所以我将sql语句的构造移到了单独的操作中。
 我想你会得到某种错误,也许Invalid column name 'EMP_CODE' ? 
这是因为代码是在检查列之前编译的。 你可以这样做,而不是。
 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 '