我正在尝试写这个查询以查找具有特定值的特定列的所有表.这是我迄今为止所做的
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 '
我希望我的内容清晰,我只想选择那些列EMP_CODE存在的那些表,在这些表中,我想选择那些EMP_CODE =’HO081’的行.
编辑 –
现在就这样但是我无法在查询中替换@EMPCODE变量.
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如何没有文档,可能会随时删除/被修改?
那么,如果你很高兴忽略它,它还有一个名为@whereand的参数,它被附加到用于查找表的内部查询的WHERE子句(并且应该以AND开头).
您还必须知道有一个别名,o针对sysobjects,另一个别名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'')'
您现在还可以简化您的命令1,因为您知道它只会针对包含EMP_CODE列的表运行.我也可能会拿出COUNT(*)条件,因为我看不到它添加了什么值.
根据您的进一步工作进行更新,并对一个表进行测试:
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)+'' 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语句的构造移动到单独的操作中.