Birisi neden SQL yan tümcesinde WHERE 1 = 1 AND <conditions> kullanır?


258

Birisi neden WHERE 1=1 AND <conditions>bir SQL yan tümcesinde kullanır? (Birleştirilmiş dizelerden elde edilen SQL, her iki görünüm tanımı)

Bir yerde bu SQL Enjeksiyon karşı korumak için kullanılacak gördüm, ama çok garip görünüyor.

Enjeksiyon WHERE 1 = 1 AND injected OR 1=1varsa ile aynı sonuca sahip olacaktır injected OR 1=1.

Daha sonra düzenleme: Bir görünüm tanımındaki kullanım ne olacak?


Cevaplarınız için teşekkür ederim.

Yine de, birisinin neden bir görünümü tanımlamak için bu yapıyı kullanacağını veya saklı yordamın içinde kullanacağını anlamıyorum.

Örneğin bunu ele alalım:

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

3
"Birisi neden bu yapıyı bir görüş tanımlamak için kullanır?" Muhtemelen alışkanlık dışında. Statik sorgularda işlevsel bir avantaj sağlamaz.
ADTC

Yanıtlar:


346

Koşullar listesi derleme zamanında bilinmiyorsa ve bunun yerine çalışma zamanında oluşturulmuşsa, bir veya birden fazla koşulunuz olup olmadığı konusunda endişelenmenize gerek yoktur. Hepsini şöyle oluşturabilirsiniz:

and <condition>

ve hepsini bir araya getirin. İle 1=1başında, başlangıç andile ilişkilendirmek için bir şey vardır.

Bunun herhangi bir enjeksiyon koruması için kullanıldığını hiç görmedim, çünkü çok yardımcı olacağını düşünmüyorsunuz. Ben var bir uygulama kolaylık olarak kullanılan görüldü. SQL sorgu motoru, 1=1performans etkisi olmaması için yok sayılır.


34
Bazen tembel olmakla ilgili değil, daha temiz bir koda sahip olmakla ilgilidir.
Eduardo Molteni

39
izleyen AND'ler veya COMMA'lar ile uğraşmak kirli değildir ... SQL'inizin her yerinde 1 = 1 olması hiçbir şey daha temiz değildir.

21
DBA? Ne için bunlar? :)
Eduardo Molteni

38
DBA'lar, veritabanlarını etkili bir şekilde nasıl kullanacaklarını bildiklerini düşünen programcılardan sonra temizlemek için oradalar.
Adrian Pronk

23
"Tembel" Akıllı olduğunu düşünüyorum, tembel değil. Tekrarlayan kod ve gereksiz koşul kontrollerinden kaçınıyorsunuz. where 1=1(Oracle) veya where true(Postgres) ekleyemeden , her koşulun ilk olup olmadığını kontrol etmem gerekecek. Bunu yapmanın bir anlamı yok ve sadece daha fazla kaynak plakası ekliyor.
ADTC

113

Greg'in cevabına örnek bir kod eklemek yeterlidir:

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

6
biraz hacky, ama geçerli bir kullanım gibi görünüyor.
Mike

5
Bu kabul edilen cevap olmalı. Uygulama sadece kaç tane koşulunuzun olduğunu belirlemek zorunda kalmamaktır.
aglassman

38

Koşul sayısı değişken olduğunda kullanıldığını gördüm.

Bir "AND" dizesi kullanarak koşulları birleştirebilirsiniz. Ardından, geçtiğiniz koşulların sayısını saymak yerine, stok SQL ifadenizin sonuna bir "WHERE 1 = 1" yerleştirir ve birleştirilmiş koşulları atarsınız.

Temel olarak, koşullar için bir test yapmanız ve ardından bunlardan önce bir "NEREDE" dizesi eklemeniz gerekir.


28

WHERE deyiminizin zaten tanımlanmış olduğunu her zaman bilmek için tembel bir yol gibi görünüyor ve ilki olup olmadığını kontrol etmenize gerek kalmadan koşullar eklemeye devam etmenize izin veriyor.


12
"Tembel" Akıllı olduğunu düşünüyorum, tembel değil. Tekrarlayan kod ve gereksiz koşul kontrollerinden kaçınıyorsunuz. where 1=1(Oracle) veya where true(Postgres) ekleyemeden , her koşulun ilk olup olmadığını kontrol etmem gerekecek. Bunu yapmanın bir anlamı yok ve sadece daha fazla kaynak plakası ekliyor.
ADTC

2
@ADTC Yazma kodu çoğunlukla - çoğunlukla olmasa da - farklı koşulların ele alınması ile ilgilidir. Bu, kişisel olarak üretilen SQL'i kirletmek için tembel olduğunu düşündüğüm, ele alınması gereken başka bir durum. Kodunuzu ONE yerine 'Where 1 = 1' eklemek için mimarsanız - çok az çaba sarf ederek - kodunuzdaki ONE yerde sıfır ve birçok koşul arasındaki farkı kaldırabilirsiniz. Tahminime göre, '1 = 1' ifadesinin onu kod tabanları boyunca serpiştiriyor, bu da beni tembellik tembellik yaratan sonuca getiriyor.
Jason S

@JasonS Laziness, Buluşun babasıdır.
ADTC

@ADTC Tembelim çünkü yüzlerce yerde kodu güncellemekten hoşlanmıyorum, bu yüzden buluş tek bir yere koyuldu. Bana göre WHERE 1=1, aynı kodu birden fazla yerde tutmak ve oluşturulan tüm SQL'de okumak için ekstra çalışma doğurur. Sandığından daha tembelim!
Jason S

19

Dolaylı Olarak İlgili: 1 = 2 kullanıldığında:

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

bu, eski tabloyla aynı şemaya sahip yeni bir tablo oluşturur. (Karşılaştırmalar için bazı veriler yüklemek istiyorsanız çok kullanışlıdır)


3
Eski tablolarla aynı verilere sahip yeni bir tablo oluşturacak olsa da, yeni tablo eski tablodaki yabancı anahtar gibi başka kısıtlamalara sahip
olmayacak

16

1 = 1 ifadesi üretilen sql kodunda yaygın olarak kullanılır. Bu ifade, koşullu deyimlerin sayısını azaltarak sql üreten kodu basitleştirebilir.


11

Aslında, BIRT raporlarında kullanılan bu tür şeyleri gördüm. BIRT çalışma zamanına iletilen sorgu şu şekildedir:

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

ve '?' çalışma zamanında bir açılır kutudan seçilen gerçek parametre değeri ile değiştirilir. Açılır menüdeki seçenekler:

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

böylece tüm olası değerleri artı " *" elde edersiniz . Kullanıcı "* açılır kutudan " (yani a'nın tüm değerleri seçilmelidir), sorgunun çalıştırılmadan önce değiştirilmesi gerekir (Javascript ile).

Beri "?" konumsal bir parametredir ve başka şeylerin çalışması için orada kalması GEREKİR, Javascript sorguyu şu şekilde değiştirir:

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

Bu, temel olarak konum parametresini yerinde bırakırken where yantümcesinin etkisini kaldırır.

Ayrıca dinamik olarak bir SQL sorgusu oluştururken tembel kodlayıcılar tarafından kullanılan AND davasını gördüm.

Dinamik olarak başlayan select * from tve kontrol eden bir sorgu oluşturmanız gerektiğini varsayalım:

  • adı Bob; ve
  • maaş> 20.000 dolar

bazı insanlar ilkini bir NEREYE ve daha sonra bir VE ile eklerler:

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

Tembel programcılar (ve bu mutlaka kötü bir özellik değildir), eklenen koşullar arasında ayrım yapmazlar, onlarla başlarlar select * from t where 1=1ve sadece AND cümleleri eklerlerdi.

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

1
"Tembel" Akıllı olduğunu düşünüyorum, tembel değil. Tekrarlayan kod ve gereksiz koşul kontrollerinden kaçınıyorsunuz. where 1=1(Oracle) veya where true(Postgres) ekleyemeden , her koşulun ilk olup olmadığını kontrol etmem gerekecek. Bunu yapmanın bir anlamı yok ve sadece daha fazla kaynak plakası ekliyor.
ADTC

1
@ ADTC, kötü bir şekilde tembel demek istemedim. Aslında, tembel programlama iyi bir özellik :-) Açıklayacağım.
paxdiablo

Tembellik tüm kötülüklerin köküdür
Ivanzinho

11

Veritabanında bir şeyleri test ederken veya kontrol ederken bu kalıbı yararlı buldum, bu yüzden diğer koşulları çok hızlı bir şekilde yorumlayabilirim:

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

dönüşür:

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

10

burada 1 = 0, Bu tablonun var olup olmadığını kontrol etmek için yapılır. Neden 1 = 1'in kullanıldığını bilmiyorum.


1
Bu, yeni kayıtlar için tutucu olarak kullanılacak veritabanından boş bir sonuç kümesi döndürmek için kullanılır.
Gary Kindel

6

Ben 1 = 1 oluşturulan SQL için yararlı olacağını görebiliyorum, ben PHP kullandığım bir teknik yan tümceleri dizisi oluşturmak ve sonra

implode (" AND ", $clauses);

böylece öndeki ya da sondaki VE Açıkçası bu sadece en az bir maddeye sahip olduğunuzu biliyorsanız faydalıdır!


1
Burada 1 = 1 devreye giriyor. Size "en az bir madde" veriyor, bu yüzden sadece "AND abc" yi tokatlamaktan endişelenmenize gerek yok
Carl

Bu fikri seviyorum! Daha eksiksiz bir örnek için buraya bakın stackoverflow.com/questions/35326160/…
drooh

5

Aşağıda yakından ilgili bir örnek verilmiştir: MERGEbirleştirilecek hedefi kaynak tablodaki tüm değerleri kullanarak tabloyu hedeflemek için bir SQL ifadesi kullanma;

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

5

Neden birisi NEREDE 1 = 1 VE <proper conditions>

Ben ettik görüldü homespun çerçeveler bu (gibi şeyler allık bu tembel ayrıştırma uygulamaları hem uygulanacak olanak sağladığından,) WHEREve ANDSQL anahtar kelimeler.

Örneğin (burada bir örnek olarak C # kullanıyorum), bir Sql sorgusunda aşağıdaki tahminlerin koşullu ayrıştırma düşünün string builder:

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

Faydasına WHERE 1 = 1 özel bir koda gerek olmadığı anlamına gelir:

  • İçin ve - sıfır, bir ya da her iki temel fonksiyonlar (Çubuklar ve Baz en) uygulanmasının gerekip gerekmediğini, burada ilk olup olmadığını belirleyecekAND gereklidir. Zaten en az bir yüklemimiz olduğu için 1 = 1,AND her zaman iyi .
  • Hiçbir tahmin için - ZERO tahminlerinin olduğu durumda, WHERE tahmin bırakılmalıdır. Fakat yine de tembel olabiliriz, çünkü yine en az bir yüklemin garantisiyiz.

Bu açık bir şekilde kötü bir fikirdir ve isteğe bağlı ve koşullu tahminleri bu şekilde ayrıştırmak için yerleşik bir veri erişim çerçevesi veya ORM kullanmanızı önerir .


Veya kendiniz yuvarlanırsanız, nerede yan tümce oluşturucu kodunuzda tek bir yerde olmalıdır. Ardından, kodunuzdaki tek bir konumda sıfır tahminlerini veya sıfırdan fazla tahminleri işleyebilirsiniz. Benim şüphe var olması WHERE 1=1durum böyle bir adil bir gösterge, kod tabanı WHERE 1=1bana bir uygulama mimarisi sorunu gösterecektir dizeleri bitleri ile çevrili olduğunu, ve ben sadece bir tahmin olduğunu!
Jason S

1
Aslında fikir hakkında "kötü" hiçbir şey, çok daha az "bariz" bir hata yoktur. ORM de her durumda doğru şekilde değildir. SQL ve İlişkisel Cebir insanlar öğrenin ...
Hejazzman

4

Aradığınız buraya geldiyse WHERE 1o notta, WHERE 1ve WHERE 1=1aynıdır. WHERE 1nadiren kullanılır, çünkü bazı veritabanı sistemleri WHERE 1gerçekten boole olmadıklarını reddeder .


2

Bu, içinde bazı filtre seçeneklerini eklemeniz gereken durumlarda dinamik sorgu kullanmanız gerektiğinde kullanışlıdır. Durum için 0, aktif için 1 seçeneklerini eklerseniz. Seçeneklerden yola çıkarak, yalnızca iki seçenek (0 ve 1) vardır, ancak Tüm kayıtları görüntülemek istiyorsanız, 1 = 1'in yakınına dahil etmek kullanışlıdır. Aşağıdaki örneğe bakın:

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

Tüm cevapları gözden geçirdikten sonra böyle bir deney yapmaya karar verdim

SELECT
*
FROM MyTable

WHERE 1=1

Sonra diğer numaralarla kontrol ettim

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

vb Tüm kontrolleri yaptıktan sonra, sorgu çalıştırmak kasaba aynıdır. nerede cümlesi olmasa bile. Ben sentaksın hayranı değilim


1

Bunu genellikle bir kullanıcının seçebileceği birçok açılan değere sahip bir rapor için dinamik SQL oluştururken yaparım. Kullanıcı her bir açılır menüden değerleri seçebileceği veya seçemeyeceği için, hangi koşulun ilk nerede cümlesi olduğunu bulmakta zorlanırız. Bu yüzden sorguyu birwhere 1=1 sonunda bundan sonra tüm cümleleri ekleriz.

Gibi bir şey

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

Sonra where yantümcesini bu şekilde oluşturur ve parametre değeri olarak iletiriz

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

Nerede cümle seçimi çalışma zamanında bilinmediği için, bu, bir 'AND' or 'WHERE'.


0

Bir yüklemi kullanmak 1=1, bazen erişim planını bir dizin taraması kullanmaya veya kullanmaya zorlamak için kullanılan normal bir ipucudur. Bunun kullanılmasının nedeni, nerede bazen tüm dizinleri kullanmanın bile erişim planının her tabloyu - tam tablo taraması - okumasına neden olduğu birçok cümle ile çok iç içe birleştirilmiş bir sorgu kullanmanızdır. Bu, DBA'lar tarafından bir dbms'yi daha verimli bir yol kullanarak kandırmak için kullanılan birçok ipucundan sadece bir tanesidir. Sadece birini atmayın; her zaman çalışmadığından sorguyu analiz etmek için bir dba gerekir.


4
Bazı veritabanları için bu davranışı belgeleyen alıntılarınız var mı?
Joe

0

İşte bir kullanım örneği ... Ancak ben neden 1 = 1 kullanmalıyım veya kullanmama teknikleriyle çok ilgili değilim. SQL Server'dan bazı verileri almak için pyodbc kullanarak bir işlev yazıyorum. whereBenim kod anahtar kelimeden sonra bir dolgu zorlamak için bir yol arıyordu . Bu gerçekten harika bir öneriydi:

if _where == '': _where = '1=1'
...
...
...
cur.execute(f'select {predicate} from {table_name} where {_where}')

Çünkü 'where' anahtar kelimesini _where yan tümcesi değişkeninin içinde birlikte uygulayamadım. Yani, doğru olarak değerlendirilen herhangi bir kukla durumu kullanmak bir dolgu maddesi olarak olacağını düşünüyorum.


-1

İlk kez ADO ve klasik asp ile karşılaştım, aldığım cevap: performans. bir düz yaparsan

Select * from tablename

ve bunu bir sql komutu / metni olarak iletin.

Where 1=1

ekledi, bu görünür bir fark oldu. ilk koşul gerçekleştiğinde tablo başlıklarının döndürülmesiyle ilgili bir şey, ya da başka bir çılgınlık, yine de, işleri hızlandırdı.


3
Bu doğruysa, DBMS neden bunu her zaman eklemiyor?
Carcamano

5
Kanıt verebilir misiniz?
Peter G.Mar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.