누군가 SQL 절에서 WHERE 1 = 1 AND <conditions>를 사용하는 이유는 무엇입니까?


257

누군가 WHERE 1=1 AND <conditions>SQL 절에서 사용하는 이유 (연결된 문자열을 통해 얻은 SQL,보기 정의 중 하나)

나는 이것이 SQL 인젝션으로부터 보호하는 데 사용될 것이라는 것을 어딘가에서 보았지만 매우 이상하게 보입니다.

주입 WHERE 1 = 1 AND injected OR 1=1이있는 경우와 같은 결과가 나타납니다 injected OR 1=1.

나중에 편집 : 뷰 정의의 사용법은 어떻습니까?


답변 주셔서 감사합니다.

그럼에도 불구하고 누군가 누군가 가이 구성을 사용하여 뷰를 정의하거나 저장 프로 시저 내에서 사용하는 이유를 이해하지 못합니다.

예를 들면 다음과 같습니다.

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

3
"왜 누군가가보기 정의이 구성을 사용합니다" 아마 습관의 아웃. 정적 쿼리에서는 기능상의 이점이 없습니다.
ADTC

답변:


346

조건 목록이 컴파일 타임에 알려지지 않고 런타임에 빌드되는 경우 하나 이상의 조건이 있는지 걱정할 필요가 없습니다. 다음과 같이 모두 생성 할 수 있습니다.

and <condition>

그것들을 모두 하나로 연결하십시오. 으로 1=1시작시, 초기가 and에 연결할 수있는 뭔가가.

나는 그것이 어떤 종류의 주사 보호에도 사용되는 것을 본 적이 없다. 나는 그것을 구현 편의를 사용 보았다. SQL 쿼리 엔진은 무시 1=1하므로 성능에 영향을 미치지 않습니다.


34
때로는 게으르지 않고 코드가 깨끗합니다.
Eduardo Molteni

39
후행 AND 또는 COMMA를 처리하는 것은 더럽지 않습니다 ... SQL 전체에 1 = 1을 가짐으로써 더 깨끗한 것은 없습니다.

21
DBA? 그들은 무엇입니까? :)
Eduardo Molteni

38
DBA는 데이터베이스를 효과적으로 사용하는 방법을 알고 있다고 생각하는 프로그래머를 쫓아냅니다.
Adrian Pronk

23
"게으른" 게으른 게 아니라 똑똑하다고 생각합니다. 반복적 인 코드와 불필요한 상태 확인을 피하고 있습니다. where 1=1(Oracle) 또는 where true(Postgres) 를 추가 할 수 없으면 각 조건이 첫 번째 조건인지 여부를 확인해야합니다. 그렇게 할 필요는 없으며 더 많은 상용구 코드 만 추가합니다.
ADTC

113

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

6
약간 해 키지 만 올바른 사용처럼 보입니다.
Mike

5
이것은 정답입니다. 연습은 실제로 당신이 얼마나 많은 조건을 결정하지 않아도 해킹입니다.
aglassman

38

조건 수를 변경할 수있을 때 사용되는 것을 보았습니다.

"AND"문자열을 사용하여 조건을 연결할 수 있습니다. 그런 다음 전달하는 조건 수를 계산하는 대신 주식 SQL 문의 끝에 "WHERE 1 = 1"을 배치하고 연결된 조건을 처리합니다.

기본적으로 조건 테스트를 수행 한 다음 "WHERE"문자열을 추가해야합니다.


28

WHERE 절이 이미 정의되어 있고 첫 번째 조건인지 확인하지 않고 조건을 계속 추가 할 수 있도록하는 게으른 방법 인 것 같습니다.


12
"게으른" 게으른 게 아니라 똑똑하다고 생각합니다. 반복적 인 코드와 불필요한 상태 확인을 피하고 있습니다. where 1=1(Oracle) 또는 where true(Postgres) 를 추가 할 수 없으면 각 조건이 첫 번째 조건인지 여부를 확인해야합니다. 그렇게 할 필요는 없으며 더 많은 상용구 코드 만 추가합니다.
ADTC

2
@ADTC 코드 작성은 종종 다른 조건을 다루는 것에 관한 것입니다. 이것은 처리해야 할 또 다른 조건이며, 개인적으로 생성 된 SQL을 오염시키는 것이 게으르다 고 생각합니다. 한 곳에서 'Where 1 = 1'을 추가하도록 코드를 설계하면 약간의 노력만으로도 코드의 한 곳에서 0과 많은 조건의 차이를 처리 할 수 ​​있습니다. 내 생각에, 'Where 1 = 1'을 옹호하는 사람들은 코드베이스 전체에 그것을 뿌려서 게으름을 느낀다는 게으름을 안겨줍니다.
Jason S

@JasonS Laziness는 발명의 아버지입니다.
ADTC

@ADTC 수백 곳의 코드를 업데이트하는 것을 좋아하지 않기 때문에 게으르다. 그래서 본 발명은 그것을 한 곳에 두었다. 나에게 WHERE 1=1동일한 코드를 여러 위치에서 유지 관리하고 생성 된 모든 SQL에서 코드를 읽는 추가 작업이 번성합니다. 내가 생각하는 것보다 게으르다!
Jason S

19

간접적으로 관련됨 : 1 = 2 사용시 :

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

이전 테이블과 동일한 스키마를 사용하여 새 테이블을 만듭니다. (비교를 위해 일부 데이터를로드하려는 경우 매우 편리합니다)


3
그것은 나이가 테이블에서 외래 키와 같은 다른 제약이 늘 오래된, 새로운 테이블과 같은 데이터를 새 테이블이 만들어집니다 동안 추가 잊어 버렸
milso

16

1 = 1 표현식은 일반적으로 생성 된 SQL 코드에서 사용됩니다. 이 표현식은 SQL 생성 코드를 단순화하여 조건문 수를 줄입니다.


11

실제로 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

게으른 프로그래머 (그리고 반드시 나쁜 특성은 아닙니다)는 추가 된 조건을 구별하지 않으며, 그 select * from t where 1=1후에 시작하고 AND 절을 추가합니다.

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

1
"게으른" 게으른 게 아니라 똑똑하다고 생각합니다. 반복적 인 코드와 불필요한 상태 확인을 피하고 있습니다. where 1=1(Oracle) 또는 where true(Postgres) 를 추가 할 수 없으면 각 조건이 첫 번째 조건인지 여부를 확인해야합니다. 그렇게 할 필요는 없으며 더 많은 상용구 코드 만 추가합니다.
ADTC

1
@ ADTC, 나는 나쁜 방식으로 게으른 것을 의미하지 않았습니다. 사실, 게으른 프로그래밍에 좋은 특성입니다 :-) 나는 명확히 할 것입니다.
paxdiablo

게으름은 모든 악의 뿌리
Ivanzinho

11

데이터베이스에서 물건을 테스트하거나 재확인 할 때이 패턴이 유용하다는 것을 알았으므로 다른 조건을 매우 빠르게 주석 처리 할 수 ​​있습니다.

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

10

where 1 = 0, 이것은 테이블이 존재하는지 확인하기 위해 수행됩니다. 1 = 1이 왜 사용되는지 모르십시오.


1
데이터베이스에서 빈 결과 집합을 반환하여 새 레코드의 홀더로 사용하는 데 사용됩니다.
게리 킨델

6

1 = 1이 생성 된 SQL에 유용하다는 것을 알 수 있지만 PHP에서 사용하는 기술은 절 배열을 만든 다음 수행하는 것입니다.

implode (" AND ", $clauses);

따라서 선행 또는 후행 AND를 갖는 문제를 피하십시오. 분명히 이것은 적어도 하나의 절을 가질 것이라는 것을 알고있는 경우에만 유용합니다!


1
1 = 1이 나오는 곳입니다. "적어도 하나의 절"을 제공하므로 "AND abc"를 두드리는 것에 대해 걱정할 필요가 없습니다
Carl

나는이 아이디어를 좋아한다! 보다 완전한 예제를 보려면 여기를 참조하십시오 stackoverflow.com/questions/35326160/…
drooh

5

밀접하게 관련된 예는 다음과 같습니다. SQL MERGE문을 사용하여 조인 할 공통 속성이없는 소스 테이블의 모든 값을 사용하여 테이블 대상을 업데이트합니다.

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

5

누가 1 = 1을 사용하고 왜 <proper conditions>

나는 한 손으로 짠 프레임 워크이 (같은 물건을 할 홍당무 이 게으른 구문 분석 사례 모두에 적용 할 수 있습니다와 같은) WHEREANDSQL 키워드.

예를 들어 (여기에서는 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특별한 코드가 필요하지 않음 을 의미합니다.

  • 들어 - 0 개, 1 개 또는 두 술어 (바, 바즈의)을 적용해야하는지 여부를 처음 여부를 결정하는 것이다 AND필요합니다. 로 적어도 하나의 술어가 이미 있으므로 항상 정상 1 = 1임을 의미 AND합니다.
  • 술어가 전혀없는 경우-ZERO 술어가있는 경우 WHERE이를 삭제해야합니다. 그러나 우리는 적어도 하나의 술어를 다시 보장하기 때문에 게으르다.

이것은 분명히 나쁜 생각이며 이러한 방식으로 선택적 및 조건부 술어를 구문 분석하기 위해 확립 된 데이터 액세스 프레임 워크 또는 ORM 을 사용하는 것이 좋습니다 .


또는 자체 롤링하는 경우 where 절 빌더가 코드의 한 곳에 있어야합니다. 그런 다음 코드의 단일 위치에서 술어 0 개 또는 술어 0 개 이상을 처리 할 수 ​​있습니다. 내 의혹은 그것이 존재 WHERE 1=1하지 않는 공정한 지표라는 것입니다. 코드베이스가 약간의 문자열로 흩어져 있습니다 WHERE 1=1. 이것은 나에게 응용 프로그램 아키텍처 문제를 나타냅니다.
Jason S

1
실제로이 아이디어에 대해 "나쁜"것은 없으며 "명백한"결함은 훨씬 적습니다. 모든 경우에 ORM이 올바른 방법은 아닙니다. SQL 및 관계형 대수를 배우십시오 ...
Hejazzman

4

을 (를) 검색 WHERE 1하려고 온 경우 WHERE 1WHERE 1=1동일합니다. WHERE 1일부 데이터베이스 시스템은 WHERE 1실제로 부울 하지 않기 때문에 거부하기 때문에 거의 사용되지 않습니다.


2

where 절에서 일부 필터 옵션을 추가해야하는 동적 쿼리를 사용해야하는 경우에 유용합니다. 상태가 0이면 비활성, 1에는 활성 옵션이 있습니다. 옵션을 기반으로 사용 가능한 두 가지 옵션 (0 및 1) 만 있지만 모든 레코드를 표시하려면 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

모든 답변을 검토 한 후 다음과 같은 실험을하기로 결정했습니다.

SELECT
*
FROM MyTable

WHERE 1=1

그런 다음 다른 숫자로 확인했습니다.

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

모든 점검을 마친 쿼리 실행 도시는 동일합니다. where 절이 없어도. 나는 구문의 팬이 아니다


1

일반적으로 사용자가 선택할 수있는 드롭 다운 값이 많은 보고서에 대해 동적 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

술어를 사용하는 1=1것은 액세스 계획이 인덱스 스캔을 사용하거나 사용하지 않도록하는 데 사용되는 일반적인 힌트입니다. 이것이 사용되는 이유는 where 절에서 많은 술어와 함께 다중 중첩 조인 쿼리를 사용하는 경우가 있습니다. 때로는 모든 인덱스를 사용하더라도 액세스 계획이 각 테이블 (전체 테이블 스캔)을 읽도록하는 경우가 있습니다. 이것은 DBA가보다 효율적인 경로를 사용하도록 dbms를 속이기 위해 사용하는 많은 힌트 중 하나입니다. 그냥 넣지 마십시오. 항상 작동하지는 않으므로 쿼리를 분석하려면 dba가 필요합니다.


4
일부 데이터베이스에 대해이 동작을 문서화 한 인용이 있습니까?
Joe

0

유스 케이스가 있습니다 ...하지만 1 = 1을 사용해야하는 이유에 대한 기술에 너무 신경 쓰지 않습니다. pyodbc를 사용하여 SQL Server에서 일부 데이터를 검색하는 함수를 작성하고 있습니다. where내 코드 에서 키워드 다음에 필러를 강제하는 방법을 찾고있었습니다 . 이것은 실제로 큰 제안이었습니다.

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

그 이유는 _where 절 변수 안에 키워드 'where'를 함께 구현할 수 없기 때문입니다. 따라서 참으로 평가되는 더미 조건을 사용하면 필러가 될 것이라고 생각합니다.


-1

나는 ADO와 고전적인 ASP와 함께이 문제를 처음 발견했다 . 똑바로하면

Select * from tablename

sql 명령 / 텍스트로 전달하면 성능이 크게 향상됩니다.

Where 1=1

덧붙여서, 그것은 눈에 띄는 차이였습니다. 첫 번째 조건이 충족 되 자마자 반환되는 테이블 헤더와 관련이 있거나 어쨌든 일부 미친 듯이 속도가 빨라졌습니다.


3
그것이 사실이라면 왜 DBMS가 항상 그것을 추가하지 않습니까?
Carcamano

5
증거를 만들 수 있습니까?
Peter G.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.