sql >> データベース >  >> RDS >> Mysql

Railsが範囲付きのwhere句のハッシュ構文を使用してクエリに`OR1 =0`を追加しているのはなぜですか?

    あなたが発見した事実に基づいて、その[1..5] 範囲を指定する正しい方法ではありません...[1..5]の理由を発見しました 動作します。そこにたどり着くために、私は最初に、ハッシュ条件の空の配列が1=0を生成することを発見しました。 SQL条件:

    User.where(id: []).to_sql
    # => "SELECT \"users\".* FROM \"users\"  WHERE 1=0"
    

    また、 ActiveRecord ::PredicateBuilder::ArrayHandlerコード 、配列値は常に範囲と他の値に分割されていることがわかります。

    ranges, values = values.partition { |v| v.is_a?(Range) }
    

    これは、1=0が表示されない理由を説明しています 範囲外の値を使用する場合。つまり、1=0を取得する唯一の方法です。 範囲を含まない配列からは、空の配列を指定します。これにより、1=0が生成されます。 上記のように、状態。そして、すべての配列に範囲が含まれている場合は、範囲条件(ranges)を取得します。 )および、個別に、空の配列条件(values )実行されました。私の推測では、これには正当な理由はないでしょう...それを回避するよりも単にこれを許可する方が簡単です(結果セットはどちらの方法でも同等であるため)。パーティションコードが少し賢い場合は、追加の空のvaluesを追加する必要はありません。 配列であり、1=0をスキップできます 状態。

    1=0の場所について そもそも…それはデータベースアダプタから来ていると思いますが、正確な場所がわかりませんでした。しかし、私はそれをレコードを見つけられない試みと呼ぶでしょう。つまり、WHERE 1=0 ユーザーを返すことはありません。これは、WHERE id=nullのような代替SQLよりも理にかなっています。 これにより、idがnullのユーザーが検索されます(これは実際には正しいSQL構文ではないことに気づきます)。そして、これは、IDが空のセットにあるすべてのユーザーを検索しようとするときに私が期待することです(つまり、nilidやnullidなどを要求していません)。ですから、私の考えでは、1=0の正確な場所について少し残しておきます。 ブラックボックスはOKなのでから来ています。少なくとも、配列内の範囲が配列を表示させている理由について推論できるようになりました!

    更新

    また、ARelを直接使用している場合でも、1=0を取得できることもわかりました。 :

    User.arel_table[:id].in([]).to_sql
    # => "1=0"
    


    1. MySQL / SQLはテキストフィールドの最初の40文字を取得しますか?

    2. エラー1265。txtファイルからデータを読み込もうとしたときに列のデータが切り捨てられました

    3. 'PDOException'構文エラーまたはアクセス違反:1064SQL構文にエラーがあります。小切手

    4. MySQLテーブルにデータを入力するためのPHPスクリプト