2016-08-28 4 views
0

すべてのデータベースで実行できるMasterデータベースにシステムストアドプロシージャを作成しました。すべてのデータベースでプロシージャを実行

use Master 
GO 

declare @sql nvarchar(1000) 

SET @sql = 'USE [?]; EXEC [dbo].[sp_procedure]' 

EXEC sp_MSforeachdb @sql 

すべてのデータベースで同じようなテーブルと列の構造を持つわけではありません。だから、内部の手続き、私はどんな計算を行う前に、次の操作を行います。

if exists(select 1 
      from 
       INFORMATION_SCHEMA.TABLES b, 
       INFORMATION_SCHEMA.COLUMNS c 
      where 
       b.TABLE_TYPE = 'BASE TABLE' 
       and b.TABLE_NAME = 'tablename' 
       and c.TABLE_NAME = b.TABLE_NAME 
       and c.COLUMN_NAME = 'columnname') 

だから、すべてのデータベースで実行中ならば、それはそのデータベースの手順をスキップしなければならない列名「ColumnNameに」と「テーブル名」という名前のテーブルがありません次のデータベースに進みます。私は、「テーブル名」テーブルを持つデータベースを持っていますが、この表の「ColumnNameに」列を持っていない、そしてそれは、このエラーを返します:

Invalid column name 'columnname'.

文の場合にif exists文が内部に入るのはなぜ?条件が満たされなくなったらすぐに終了してはいけませんか?このような状況にどう対処することができますか?

+0

[習慣が悪い:古いスタイルのJOINを使用する](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style- ANSI - ** 92 ** SQL標準(** 20年以上**)の*正しい* ANSI 'JOIN'構文で置き換えられた古いスタイルの*カンマ区切りのテーブル*前に)、その使用はお勧めしません。 –

答えて

2

これは、SQLエンジンがコードをコンパイルしようとするため、IFブロック内のコードをチェックするためです。

この比較は、ストアドプロシージャの外部で使用する必要があります。 SET @sql = '......'コマンドでは、列が存在しない場合はそのSPを実行しません。

これで、SP内でクエリ(nvarchar変数)を構築し、動的SQLとして実行することができます。

+0

正確に。ありがとう、@Anton – Sher

関連する問題