17

特定の値を持つ特定の列を持つすべてのテーブルを検索するために、このクエリを作成しようとしています。これは私がこれまで何をやったかである -SQL Server sp_msforeachtableは、ある条件を満たすテーブルのみを選択するために使用します。

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='''[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]+''')' 

答えて

45

あなたはsp_MSforeachtableが文書化されていないで、いつでも離れて行くこと/変更することが方法を知っていますか?あなたはそれを無視して幸せなら

まあ、それはテーブルを検索するために使用されている(とANDで始める必要があります)内部クエリのWHERE句に追加され@whereandと呼ばれる別のパラメータを持っています。

また、別名osysobjectsとの間に、別名sysosys.all_objectsがあることも知っておく必要があります。あなたはそれが唯一のEMP_CODE列を含む表に対して実行されます知っているので、あなたは今も、あなたのcommand1を簡素化することができます

EXEC sp_MSforeachtable 
@command1='...', 
@whereand='AND o.id in (select object_id from sys.columns c where c.name=''EMP_CODE'')' 

:この知識を使用して

、あなたはとしてあなた@whereandパラメータを作るかもしれません。私はおそらく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='''[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'')' 

あなたがそこに価値を交換したくないので、(私は、EMP_CODEを照会する@whereandを戻ってきた:あなたの更なる作業に基づいて、一つのテーブルに対してテストを更新


)。

問題は、ストアドプロシージャへパラメータ、またはリテラルを渡すことができますが、それらの間のアクションを組み合わせた/計算を行うことができない、ということである - ので、私はに出て、SQL文の構築を移動しました別のアクション。

+4

+1;?) – cairnz

+0

私は 'IF(SELECT COUNT(*)FROM書く場合とし@Damien_The_Unbeliever WHERE EMP_CODE = '' '+ @EMPCODE + '' ')> 0'それから、なぜ私に与えるのですか? '+'の近くに不正な構文があります。 'EMP_CODE'の値を変数に渡そうとしています。 –

+0

@SohamDasguptaは - 私は本当にそれが今立っているとして、全体のクエリを確認する必要があるだろう、それはコメントで作業するつもりはないので、それは、コメント欄でこの種の問題を診断するには少しトリッキーです。私はその特定のコードを再度クエリするでしょう - 単純にそれらを選択するのではなく、一致する行の数を*カウントする*理由は何ですか?空の結果セットは、通常扱いやすいです。 –

9

おそらく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 
' 
+0

素晴らしい作品です。ありがとう。 –

関連する問題