2017-04-21 5 views
0

私はSql ServerでSSMSで実行している以下のスクリプトを持っています。私は自分のテーブルのどの列が列名のどこかに「時間」を持っているかを調べようとしています。selectの文字列リテラルは、変数を使用するときに何か違うものを返します

最初の選択は、アクセスされているテーブルで使用可能な列を示します。

次の2つは私の質問です。最初の変数は、変数@timeColumnをN '%time%'を探している文字列に設定し、2番目の変数はリテラルを使用します。私はこれらの2つが同じ列名を返すことを期待するだろうが、それらはしません。なぜどんなアイデア?

USE MyLargeDB 
declare @tableName NVARCHAR(100), @timeColumn NVARCHAR(100), @foundTimeCol NVARCHAR(100) 
Set @tableName = N'Faults' 
SET @timeColumn = N'%time%' 
SELECT * 
    FROM sys.columns 
    WHERE Name LIKE @timeColumn 
     AND Object_ID = Object_ID(@tableName) 

SET @foundTimeCol = (SELECT top 1 Name 
    FROM sys.columns 
    WHERE Name LIKE @timeColumn 
     AND Object_ID = Object_ID(@tableName)) 

print 'Found column with variable: ' + @foundTimeCol 

SET @foundTimeCol = (SELECT top 1 Name 
    FROM sys.columns 
    WHERE Name LIKE N'%time%' 
     AND Object_ID = Object_ID(@tableName)) 
print 'Found column with literal string: ' + @foundTimeCol 

出力:enter image description here enter image description here

+1

あなたはデータが一貫性のために戻って来てほしい場合は、ORDER BY句を指定する必要があります。それ以外の場合は、SQLが毎回同じ順序でデータを提供するという保証はありません(通常はそうであるように見えます)。 – EMUEVIL

答えて

3

あなたは結果が注文されていると仮定し、あなたのSELECTで "TOP 1" を使用しています。両方のSELECT TOP 1ステートメントに "ORDER BY Name"を追加して同じ結果を得ます。もちろん、これは可能なマッチのうちの1つを返すだけです。このような

何か:

SET @foundTimeCol = (SELECT top 1 Name 
FROM sys.columns 
WHERE Name LIKE @timeColumn 
    AND Object_ID = Object_ID(@tableName) 
    ORDER BY Name) 
+0

私はORDER BYがそれを修正すると考えましたが、なぜそれが理解できませんでした。だから私はそれが私がそれを走らせるたびに同じ値を返すということはただの運が良かったと思う。それを説明してくれてありがとう。 –

+1

ORDER BYが指定されていないTOP 1は、最初に見つかったものを返します.SQL Serverインスタンスがクエリを満たすために使用するプランによって異なり、そのプランは実行ごとに異なる場合があります。 SQL自体にわずかな変更が加えられました。あなたが "TOP"を使うときは、いつも "ORDER BY"が必要です。それは決定的ではありません。 – pmbAustin

関連する問題