2009-08-29 14 views
3

SQL Server 2005で次のステートメントを実行すると、最初の実行時に成功し、後続の実行で失敗します。これが何を意味するのか選択が不一致の列で失敗する

IF OBJECT_ID('tempdb..#test') IS NULL 
    CREATE TABLE #test (GoodColumn INT) 
IF 1 = 0 
    SELECT BadColumn 
    FROM #test 

は何かが、私はスクリプトが「コンパイル」されたときに、テーブルの上に存在する列に対する私のSELECT文でアクセスしていますが、列を比較していることです。私の目的のために、これは望ましくない機能性です。私の質問は、このコードが実行されるたびに正常に実行されるように何かができるかどうか、あるいはそれが可能でない場合は、なぜデモンストレーションされた機能が望ましいのかを説明できるかもしれません。私が現在行っている唯一の解決策は、選択をEXECまたは選択*で囲むことですが、どちらの解決策も嫌いです。

おかげで、この動作は、プログラマの観点から、「望ましい」であるか否かは、

答えて

0

はもちろん議論の余地がある - それは、基本的には静的型付けと動的型付け言語の違いにまで来ています。 SQL Serverは、実行計画(およびキャッシュ実行計画)をコンパイルおよび最適化するために、完全な情報を必要とするため、パフォーマンス上の観点から望ましいものです。

言い換えれば、T-SQLはではありません。は、解釈された、または動的に型指定された言語なので、このようなコードを書くことはできません。オプションは、EXECを使用するか、別の言語を使用してその中にSQLクエリを埋め込むかのいずれかです。

3

あなたが置く場合:

IF OBJECT_ID('tempdb..#test') IS NOT NULL 
    DROP TABLE #test 
GO 

を開始時#testテーブルが存在する前に、バッチが解析されますよう、問題は、離れて行くでしょう。

「1 = 0」が常にfalseと評価されることをシステムが認識することが求められます。それが本当であれば(実際の状況では潜在的に可能性があります)、失敗の原因となるものを実行しようとしていることが分かります。

あなたは一時テーブルをドロップして、同じことをストアドプロシージャを作成した場合:次に、これは楽しそうに作成されます

CREATE PROC dbo.test 
AS 
BEGIN 
    IF OBJECT_ID('tempdb..#test') IS NULL 
    CREATE TABLE #test (GoodColumn INT) 

    IF 1 = 0 
    SELECT BadColumn 
    FROM #test 
END 

を、あなたが好きなようにあなたはそれのように何度も実行することができます。

ロブ

+0

私はSQLで両方のソリューションを試してみましたが、両方が「無効な列名 『BadColumn』で失敗します。" –

+0

一時オブジェクトが存在しない場合、このdbo.test procを作成して繰り返し実行することができます。一時オブジェクトが存在する場合、エラーが発生します。 –

+0

+1。テーブルはBadCOlumnが見つからないことを意味し、 "遅延名解決"が後の使用に適用されます。 – gbn

0

この問題は、これらの状況にも見える:

IF 1 = 1 
    select dummy = GETDATE() into #tmp 
ELSE 
    select dummy = GETDATE() into #tmp 

番目のステートメントは、同じエラーが発生し実行されることはありませんが。 クエリエンジンの第1レベルの検証は、すべての条件文を無視しているようです。

0

次のリクエストで問題が発生しているとします。これは、オブジェクトが既に終了しているためです。テンポラリテーブルをできるだけ早く削除することをお勧めします。

で一時テーブルのパフォーマンスについて詳しく読む: SQL Server performance.com

関連する問題