web-dev-qa-db-ja.com

SQL句でWHERE 1 = 1 AND <conditions>を使用するのはなぜですか?

なぜ誰かがSQL句でWHERE 1=1 AND <conditions>を使用するのか(連結された文字列、またはビュー定義から取得されたいずれかのSQL)

SQLインジェクションから保護するためにこれが使用されることをどこかで見ましたが、非常に奇妙に見えます。

注入がある場合、WHERE 1 = 1 AND injected OR 1=1injected OR 1=1と同じ結果になります。

後の編集:ビュー定義での使用法はどうですか?


ご回答ありがとうございます。

それでも、なぜ誰かがこの構造を使用してビューを定義したり、ストアドプロシージャ内で使用したりするのか理解できません。

これを例に取ります:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
232
Bogdan Maxim

コンパイル時に条件のリストがわからず、代わりに実行時に作成される場合、1つまたは複数の条件があるかどうかを心配する必要はありません。これらはすべて次のように生成できます。

and <condition>

それらをすべて連結します。 1=1を開始すると、最初のandに関連付けるものがあります。

あなたがそれが多くの助けになるとは思われないと言うので、私はこれがどんな種類の注射保護にも使われるのを見たことがありません。 I have実装の便宜として使用されているのを見た。 SQLクエリエンジンは1=1を無視するため、パフォーマンスへの影響はありません。

321
Greg Hewgill

Gregの答えにサンプルコードを追加するだけです。

dim sqlstmt as new StringBuilder
sqlstmt.add("SELECT * FROM Products")
sqlstmt.add(" WHERE 1=1") 

''// From now on you don't have to worry if you must 
''// append AND or WHERE because you know the WHERE is there
If ProductCategoryID <> 0 then
  sqlstmt.AppendFormat(" AND ProductCategoryID = {0}", trim(ProductCategoryID))
end if
If MinimunPrice > 0 then
  sqlstmt.AppendFormat(" AND Price >= {0}", trim(MinimunPrice))
end if
112
Eduardo Molteni

条件の数が可変の場合に使用されるのを見てきました。

「AND」文字列を使用して条件を連結できます。次に、渡す条件の数をカウントする代わりに、ストックSQLステートメントの最後に「WHERE 1 = 1」を配置し、連結された条件にスローします。

基本的に、条件のテストを行ってから、「WHERE」文字列を条件の前に追加する必要がなくなります。

36
Carl

WHERE句が既に定義されていることを常に把握し、最初の条件であるかどうかを確認せずに条件を追加し続けることができる怠laな方法のようです。

26
duckworth

間接的関連:1 = 2が使用される場合:

CREATE TABLE New_table_name 
as 
select * 
FROM Old_table_name 
WHERE 1 = 2;

これにより、古いテーブルと同じスキーマを持つ新しいテーブルが作成されます。 (比較のためにいくつかのデータをロードしたい場合に非常に便利です)

16
milso

1 = 1式は、生成されたSQLコードで一般的に使用されます。この式により、SQL生成コードが単純化され、条件ステートメントの数が削減されます。

15
aku

ここで、1 = 0、これはテーブルが存在するかどうかを確認するために行われます。 1 = 1が使用される理由がわかりません。

11
asd

実際、私はBIRTレポートで使用されているこの種のものを見てきました。 BIRTランタイムに渡されるクエリの形式は次のとおりです。

select a,b,c from t where a = ?

そしてその '?'実行時に、ドロップダウンボックスから選択された実際のパラメーター値に置き換えられます。ドロップダウンの選択肢は次のとおりです。

select distinct a from t
union all
select '*' from sysibm.sysdummy1

すべての可能な値に加えて「*」を取得します。ユーザーがドロップダウンボックスから「*」を選択した場合(aのすべての値を選択する必要があることを意味します)、クエリを実行する前に(Javascriptによって)変更する必要があります。

「?」は位置パラメータであり、他の機能が動作するためにそこに残らなければなりません。Javascriptはクエリを次のように変更します。

select a,b,c from t where ((a = ?) or (1==1))

基本的には、位置パラメータをそのまま残したままwhere句の効果を削除します。

また、SQLクエリを動的に作成する際に、遅延コーダーが使用するANDケースも確認しました。

select * from tで始まり、チェックするクエリを動的に作成する必要があるとします。

  • 名前はボブです。そして
  • 給料は20,000ドル以上

一部の人々は、最初にWHEREを追加し、その後にANDを追加します:

select * from t where name = 'Bob' and salary > 20000

怠zyなプログラマー(そして、それは必ずしもbad特性ではない)は、追加された条件を区別せず、select * from t where 1=1で始まり、その後にAND句を追加するだけです。

select * from t where 1=1 and name = 'Bob' and salary > 20000
11
paxdiablo

データベースのテストやダブルチェックを行うときにこのパターンが役立つことがわかったので、他の条件を非常にすばやくコメントできます。

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
AND Table.Field=Value
AND Table.IsValid=true

になる:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
--AND Table.Field=Value
--AND Table.IsValid=true
8
Carlos Toledo

生成されたSQLには1 = 1が役立つことがわかりますが、PHPで使用する手法は、句の配列を作成してから

implode (" AND ", $clauses);

したがって、先行または後続のANDを使用する問題を回避できます。明らかに、これは少なくとも1つの節があることを知っている場合にのみ役立ちます!

6
sanbikinoraion

密接に関連する例は次のとおりです。SQLMERGEステートメントを使用して、ソーステーブルからのすべての値を使用してターゲットテーブルを更新します。

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;
5
onedaywhen

誰かがWHERE 1 = 1 AND <proper conditions>を使用する理由

seen homespunフレームワークはこのようなことを行います(blush)。これにより、遅延解析構文をWHEREname__とANDSqlキーワードの両方に適用できます。 。

たとえば(ここでは例としてC#を使用しています)、SQLクエリstring builderの次の述語の条件付き解析を検討してください。

var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
    sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
    sqlQuery = sqlQuery + " AND Baz < 12";
}

WHERE 1 = 1の「利点」は、特別なコードが必要ないことを意味します。

  • および-ゼロ、1つ、または両方の述語(バーとバズ)を適用するかどうか。最初のANDname__が必要かどうかを決定します。 1 = 1には少なくとも1つの述語がすでにあるため、ANDname__は常にOKです。
  • 述語がまったくない場合-述語がゼロの場合、WHEREname__を削除する必要があります。しかし、ここでも、少なくとも1つの述語が保証されるため、怠zyになる可能性があります。

これは明らかに悪い考えであり、確立されたデータアクセスフレームワークまたは ORM を使用して、この方法でオプションおよび条件付き述語を解析することをお勧めします。

5
StuartLC

WHERE 1を探してここに来た場合は、WHERE 1WHERE 1=1が同じであることに注意してください。 WHERE 1は、WHERE 1が実際にはブール値ではないと見なして拒否するデータベースシステムがあるため、めったに使用されません。

4

すべての答えを確認してから、次のような実験を行うことにしました

SELECT
*
FROM MyTable

WHERE 1=1

次に、他の番号で確認しました

WHERE 2=2
WHERE 10=10
WHERE 99=99

ectすべてのチェックを行った後、クエリ実行タウンは同じです。 where句がなくても。私は構文のファンではありません

2
JonWay

これは、where句にフィルターオプションを追加する必要がある動的クエリを使用する必要がある場合に役立ちます。ステータスが非アクティブの場合はオプション0、アクティブの場合は1を含めると同様です。オプションに基づいて、2つの使用可能なオプション(0と1)のみがありますが、すべてのレコードを表示する場合は、close 1 = 1の場所に含めると便利です。以下のサンプルを参照してください。

Declare @SearchValue    varchar(8) 
Declare @SQLQuery varchar(max) = '
Select [FirstName]
    ,[LastName]
    ,[MiddleName]
    ,[BirthDate]
,Case
    when [Status] = 0 then ''Inactive''
    when [Status] = 1 then ''Active''
end as [Status]'

Declare @SearchOption nvarchar(100)
If (@SearchValue = 'Active')
Begin
    Set @SearchOption = ' Where a.[Status] = 1'
End

If (@SearchValue = 'Inactive')
Begin
    Set @SearchOption = ' Where a.[Status] = 0'
End

If (@SearchValue = 'All')
Begin
    Set @SearchOption = ' Where 1=1'
End

Set @SQLQuery = @SQLQuery + @SearchOption

Exec(@SQLQuery);
2
Eliseo Jr

1=1のような述語を使用することは、インデックススキャンを使用するか使用しないかをアクセスプランに強制するために時々使用される通常のヒントです。これが使用される理由は、where句に多くの述語を含む複数のネストされた結合クエリを使用している場合です。これは、DBMSがDBMSをだましてより効率的なパスを使用するために使用する多くのヒントの1つにすぎません。ただ投げ込まないでください。クエリが常に機能するとは限らないため、クエリを分析するにはdbaが必要です。

0
Big Al

ユーザーが選択できる多くのドロップダウン値を持つレポート用の動的SQLを作成するときに、通常これを行います。ユーザーは各ドロップダウンから値を選択する場合としない場合があるため、どの条件が最初のwhere句であるかを判断するのに苦労します。そのため、クエリの最後にwhere 1=1を埋め込み、その後にすべてのwhere句を追加します。

何かのようなもの

select column1, column2 from my table where 1=1 {name} {age};

次に、このようなwhere句を作成し、パラメーター値として渡します

string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";

実行時にwhere句の選択が不明なので、これは'AND' or 'WHERE'.を含めるかどうかを見つけるのに非常に役立ちます

0
Zo Has