このクエリを作成して、特定の値を持つ特定の列を持つすべてのテーブルを検索しようとしています。これは私がこれまでにやったことです-
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
_が文書化されておらず、いつでも消える/修正される可能性があることを知っていますか?
それを無視してよければ、テーブルを見つけるために使用されている内部クエリのWHERE
句に追加される_@whereand
_という別のパラメータがあります(開始する必要があります) AND
)。
また、o
に対するsysobjects
エイリアスと、_sys.all_objects
_に対する2番目のエイリアスsyso
があることも知っておく必要があります。
この知識を使用して、_@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(*)
条件も削除します。
今後の作業に基づいて更新し、1つのテーブルに対してテストしました。
_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
_を照会しました。そこで値を置き換えたくないので)。
問題は、parametersをストアドプロシージャに渡すことができる、またはliteralsを渡すことができるが、それらの間で計算/アクションの組み合わせを実行できないことです。 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
'