Wiesz, jak sp_MSforeachtable
jest nieudokumentowany i może w każdej chwili zniknąć/zostać zmodyfikowany?
Cóż, jeśli z przyjemnością to zignorujesz, ma inny parametr o nazwie @whereand
, który jest dołączany do WHERE
klauzula wewnętrznego zapytania, które jest używane do znalezienia tabel (i powinno zaczynać się od AND
).
Musisz także wiedzieć, że istnieje alias, o
przeciwko sysobjects
i drugi alias syso
przeciwko sys.all_objects
.
Korzystając z tej wiedzy, możesz stworzyć swój @whereand
parametr jako:
EXEC sp_MSforeachtable
@command1='...',
@whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')'
Możesz teraz również uprościć swoje command1
, ponieważ wiesz, że będzie uruchamiany tylko w przypadku tabel zawierających EMP_CODE
kolumna. Prawdopodobnie wyjąłbym COUNT(*)
warunek również, ponieważ nie widzę, jaką wartość dodaje.
Zaktualizowano na podstawie Twojej dalszej pracy i przetestowano na jednej tabeli:
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'')'
(Przywróciłem @whereand
zapytanie o EMP_CODE
, ponieważ nie chcesz zastępować tej wartości).
Problem polega na tym, że możesz przekazywać parametry do procedury składowanej lub literałów , ale nie możesz wykonywać obliczeń/łączenia akcji między nimi - więc przeniosłem konstrukcję instrukcji sql do osobnej akcji.