2016-01-03 6 views
5

特定の条件を持つレコードが存在しない可能性があるテーブルが存在するかどうかをチェックする必要があり、これをスカラー関数で行う必要があります。ここで存在しない可能性のあるレコードがあるかどうかを確認する

は私のコードです:

CREATE FUNCTION CheckIfRecordsExistInTestTable() 
RETURNS INT 
BEGIN 
DECLARE @Result INT 
SELECT @Result = 
CASE WHEN OBJECT_ID('TestTable') IS NULL THEN 0 
ELSE 
CASE WHEN EXISTS(SELECT * FROM TestTable) THEN 
1 
ELSE 
0 
END 
END 
RETURN @Result 
END 

次の文を実行してSQL Serverでそれをしようとしている間:

SELECT dbo.CheckIfRecordsExistInTestTable() 

TestTableが、それは私の予想結果を返しますが存在するたびに。しかし、SQL Serverは例外が発生するたびに(無効なオブジェクト名 'TestTable')、私は期待したものを得ることができません(この状況ではゼロ戻り値が必要です)。 スカラー関数にコード化できるこの問題に対して、あなたは何を提案しますか?

答えて

4

あなたがマーティンの答えをチェックしてきているエラーの背後にある理由についての詳細を知るためにはfunction

このような
CREATE FUNCTION Checkifrecordsexistintesttable() 
returns INT 
    BEGIN 
     DECLARE @Result INT 

     IF Object_id('TestTable') IS NULL 
     SET @Result = 0 
     ELSE 
     SELECT @Result = CASE 
          WHEN EXISTS(SELECT 1 FROM testtable) THEN 1 
          ELSE 0 
         END 

     RETURN @Result 
    END; 

を変更してみてください。

5

もう1つの回答が正しい回避策を示します。あなたは問題を得ている理由として

...

これは、コンパイル時のエラーです。

ステートメントが存在しないオブジェクトコンパイルを参照する場合、実行直前まで延期されますが、最終的にはステートメント全体が実行前に実行計画にコンパイルされる必要があります。

テーブルが存在しないにもかかわらず、そのステートメントの実行が開始されない場合、これは失敗します。

(それを作成しようと実行計画 - ケースが満たされない場合は条件の評価を回避するために、passthru predicateを使用して)testtableに対してSELECTが中に移動されている回避策で

enter image description here

異なるステートメント。このステートメントのコンパイルはまだ延期されており、ステートメントは決して実行されないため、すべて正常に動作します。このような

+2

あなたは天才の男です。私は私の答えを更新しました。 'Sql Server'の初心者で、これらのことをすべて学んでいます:) –

0

更新機能は:

CREATE FUNCTION CheckIfRecordsExistInTestTable() 
RETURNS INT 
BEGIN 
DECLARE @Result INT 
SELECT @Result = case when count(1) = 0 then 0 else 1 end from sys.tables where name = 'TestTable' 

RETURN @result 

END 
関連する問題