제타건담
5k
2014-05-20 14:39:18
64
32257

동적 쿼리 만들때 where 1=1 쓰면 안되는 이유에 대하여..


동적 쿼리 만들때 where 1=1을 쓰지 말아야 하는 이유에 대하여..

안녕하세요..
예전에 이 부분에 대해 댓글을 달은적이 있었습니다..
그때 저는 where 1=1을 쓰면 안된다고 했습니다..잠재적 버그를 양산한다고 했죠..
그거에 대해 충분한 이유도 설명했는데..잘못 생각했다고 시인하라는 사람까지 나오더군요..
이 방법을 생각한 사람이 울며 쓰러지겠다고 하더군요..
저는 그 사람이 울며 쓰러지는 것엔 관심 없습니다..버그가 없는게 중요한거지..
물론 그거에 댓글도 달았습니다만..
이 자리를 빌어 왜 그걸 쓰면 안되는지에 대한 제 생각과 여러분의 생각을 듣고자 글을 씁니다..

일단 제가 where 1=1을 사용하면 안되는 이유부터 먼저 말씀 드릴께요..

예를 들어 memid와 name을 동적으로 값을 받아 회원 정보 1명것을 리턴하는 쿼리를 만든다고 가정을 하겠습니다..
select memid, name, address
from member
where 1=1
and memid='terry' -- memid 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..
and name='Terry' -- name 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..

그런데..어떤 이유에선지..memid와 name이 모두 null로 들어왔다면 최종 만들어지는 sql문은 다음과 같이 될껍니다..
select memid, name, address
from member
where 1=1

이러면 모든 회원 정보를 리턴하는 쿼리이기 때문에 복수개의 행이 리턴되겠죠..

그리고 이러한 기법을 delete문에서 쓴다고 가정해보죠..
delete from member
where 1=1
and memid='terry' -- memid 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..
and name='Terry' -- name 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..

마찬가지로 어떤 이유에선지 memid와 name 모두 null로 들어왔다면 최종 만들어지는 sql문은 다음과 같이 될껍니다..
delete from member
where 1=1

이러면 회원 정보 전부가 삭제되겠죠..

잠재적 버그 양산..이란건 다른게 아닙니다..너무나 당연하듯이 이런걸 써버리면 이런점을 고려하지 않고 그만큼 많이 사용되기땜에 ..
양산이 된다는겁니다..
그리고 막상 이런일이 터질경우..
개발자 머리는..

나는 모든 상황에 대해 null 체크를 다 했기 때문에 이런일은 절대 일어날수 없어..

라고 먼저 생각하기 때문에 이런 쿼리문에 과연 null이 들어와서 작동을 할수 있을까..하는 선입견에 사로잡히다보니..
버그 추적이 더 힘들어집니다..

물론 null 체크는 남이 얘기하지 않아도 당연 해야 하는 겁니다..
그러나 더 베스트한 방법은 애초에 1=1 이란 구문이 쿼리문에 들어가지 않으면..
설사 내가 null 체크하는 부분을 실수로 빼먹었다 해도..
쿼리가 쿼리문 오류를 일으켜서 실행을 안하는 쪽으로 가지..
회원테이블 데이터 전부 삭제..같은 엄청난 오류를 일으키지는 않는다는거죠..

이래도 1=1을 쓰시겠다면 말리진 않겠습니다..
그러나 이 방법이 잘못생각했다..라는 생각엔 동의할순 없습니다..
심지어 그렇게 말한 사람은 논리적 오류..라고 얘기하던데..제가 얘기한 부분에서 어느 부분이 논리적 오류..라는건가요?
사전에 개발자들이 null 체크를 모두 하기 때문에 저런일이 일어나지 않는다..라고 하는 생각인가요?
그렇게 말하는 사람들에게 이렇게 얘기하고 싶네요..


당신은 실수 안하십니까..?


회원정보 삭제에서 실수로 null 체크 로직 하나 빼먹은 뒤에 운영테이블에서 회원 정보 다 날리고 나서야..
제가 실수했어요..이렇게 얘기하실껀가요..?

물론 너무 억지..라고 얘기할수 있습니다..
그러나 버그란..그런 억지스러운 상황에서 일어나기 마련입니다..
우리 머릿속에 예측 가능한 상황은 버그가 아닙니다..
예측 가능한 상황이면 고칠수 있는 것이기에 버그가 있을수 없죠..
예측 가능한 상황에서 처리 안했으면 그건 본인의 업무에 대한 망각입니다..
예측 불가능한 상황에서 오는 것이 버그인거죠..

제 글에 대해 제가 논리적인 오류가 있다고 하면 시인하겠습니다..
저도 그러면서 배우는거니까요..
그러니 제 의견에 다른 의견이 있으시면 댓글로 알아주시면 겸손히 받겠습니다..

추가) 댓글로 달아주신 내용중에 부가설명할것이 있어서 수정합니다..
일단 제가 위에서 예를 들어드린 select문은 1개의 회원정보를 조건값에 따라 return 하는 경우로 예를 들어드린겁니다..
그리고 복수개일때도 쓰면 안되는 이유를 말씀드리죠..
예를 들어 다음의 쿼리문이 있다고 가정해보죠..

select memid, name from board
where 1=1
and memid = abc -- memid 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..
and name = def -- name 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..
order by memid

근데 이 board 테이블의 현재 상태가 개발중의 태스트하는 극단(?)적인 상황이어서..
전체 1만건에 memid가 abc이고 memname이 def인 것이 9999건이 있고..
memid가 terry이고 memname이 Terry인것이 1건 있다고 가정해보죠..
그리고 저걸 페이징에 사용된다고 하고 가정하죠..

그러면 나는 memid와 name을 null 체크 하는 것을 실수로 잊어먹었을 경우 화면에서는 내가 검색 조건에서 memid를 abc를 주어도 memid와 name이 모두 null로 들어오겠죠..

그럼 쿼리는 다음과 같이 만들어질껍니다..

select memid, name from board
where 1=1

네..이러면 1페이지는 정상적으로 보일꺼에요..왜냐면 order by를 했기땜에 1페이지에 abc가 나올테니까요..
그러고 개발자는 잘 동작하네..하고 다 개발됐구나..라고 생각할껍니다..
정작 마지막 페이지에 terry가 있는것은 확인 못한채 말이지요..

이게..복수행에서 정상동작 한다고 해서 다 되는게 아닙니다..
1페이지에서 오류가 발생해서 잡을수 있는 상황이면 모르겠지만..
이런 예에서 누가 마지막까지 데이터를 확인하겠습니까..?

어느 분이 실행계획..을 얘기하시는데..저는 이것을 실행계획이 달라서..란 의도로 말씀드린게 아닙니다..실행계획 관점이라면 애초에 실행계획이 이러이러해서..이렇다라고 설명했을겁니다..
2
5
  • 답변 64

  • 믿음
    4k
    2014-05-20 14:07:02
    Terry님// 항상 좋은 글 감사합니다.
    0
  • 개나소나고생
    4k
    2014-05-20 14:07:33
    네...안녕하세요..근데..프로시저에서는 저렇게 사용하면 문제가 되나요?

    제가 다니느 회사의 경우 사내 모든 동적 쿼리 조회 하는 Where 조건 문제 where 1=1 구문을 사용하고 있습니다.근데..현재 까지 저런 문제는 없어서요.
    0
  • 믿음
    4k
    2014-05-20 14:11:02
    ㄴㅇㄴㅇㄴㅇ님// Terry님 글을 보면 문제 발생하기 때문에 사용하지 말라는 의미는 아닌것 같아요.
    잠재적 문제를 방생시킬 수 있는 요소이기 때문에 문제가 없더라도 사용을 하지 말자는 의미인거죠. ㅎㅎㅎ
    0
  • 뒷집할머니
    980
    2014-05-20 14:16:55
    memid 와 name 모두 null 일 때
    쿼리로 안 넘어가게 처리만 하면 문제될 것 없어보이는데요.
    0
  • 지아빠
    1k
    2014-05-20 14:19:19
    select myid, mypasswd, myname
    from member
    where 1=1

    select myid, mypasswd, myname
    from member

    이 두개의 쿼리가 다른 건가요
    결과적으로 같고 실행계획도 동일한데요

    where 1 = 1 : 참
    and field_c= 'ccc' : 참 또는 거짓

    이 두개의 조건일 경우 1=1 무조건 참이기 때문
    field_c= 'ccc' 의 경우가 참인가 거짓이냐에 따라 조건이 성립되지
    1=1 참이라고 다 조회된다고 생각하시는게 이상한거 같아요.
    0
  • 스티븐잡부
    1k
    2014-05-20 14:19:27
    제가 이 대화에 감히 껴도 될지 모르겠는데... 상황에 따라 다르지 않을까요?
    일단 delete문에 쓰는건 아니라고 생각합니다. 그동안 감히 생각해본적도 없었고 delete는 정말 딱 조건에 맞는 경우에만 삭제하도록 늘 로직을 짜왔기 때문에

    그런데 select문 같은 경우는 예를들어 어떤 공통코드를 조회하는 화면이라고 쳤을때 거기에는 그걸 구분하는 조건을 선택하는 콤보박스라던지 그런게 있겠죠. 만약 아무것도 입력이 안되어 있는 경우에는 전체를 조회하도록 로직을 생각했다면 where 1 = 1 이 문제되진 않는다고 생각합니다. 그런데 개발자가 의도하지 않게 where 1 = 1 의 조회조건이 들어가는 일이 생긴다면 그건 분명히 문제이고요
    0
  • ymtsss1
    101
    2014-05-20 14:20:12
    쓰면 안된다라기보다는 비추천이다 그리고 사용시 조건문에 주의하여야된다라고

    표현하는게 맞지않을까요?
    (조건이 누락될경우 where 1=1 이 있든 없든 다 삭제 되는건마찬가지 일거 같은데)
    0
  • 제타건담
    5k
    2014-05-20 14:20:40
    //믿음
    네..맞습니다..지금 당장은 잘 돌아가고 있을순 있겠죠..null 체크도 항상 하던대로 하고..그렇다면 지금은 별 문제 없겠죠..
    그러나 이것이 확장이 되면서 다른 사람들이 붙고..그 사람들이 나 같지가 않아서 null 체크에 소홀히 하고 그러면..저런 잠재적인 버그가 활동하게 된다는거죠..
    실수는 할수 있다..라는 가정하에서 생각을 해보세요..그러면 실수를 했을 경우 어떻게 전개되면 사후 처리를 덜 할수 있는 쪽으로 갈까요?
    전체 회원 정보 삭제된걸 뒤늦게 발견하여 다시 백업된거 복구하며 그렇게 시간을 보내는게 나을지..아니면 애초에 실행이 안되어서 코드상에서 오류를 수정하는게 나을지를요..
    0
  • 제타건담
    5k
    2014-05-20 14:23:47
    // 폼나게살자
    제가 본문에 예를 들어드렸자너요..1개의 회원행을 조건에 따라 리턴하는거라구요..
    애초에 복수개를 return 하는 걸로 되어 있고 그것에 조건이 1=1로 있다면 결과는 관계가 없겠죠..
    복수개의 행을 리턴하는 것을 전제로 해서 짠 쿼리였다면 1=1은 큰 영향은 없죠..
    0
  • vsanv614
    -661
    2014-05-20 14:28:24
    좋은 글 감사합니다..

    정말 실수를 하고싶어서 하는 것도 아니고 ㅠㅠㅠㅠㅠㅠㅠㅠ

    0
  • fx
    977
    2014-05-20 14:29:02
    위에 폼나게 살자님이 쓰신 예처럼 동적쿼리 만들때,

    delete from member
    where 1=1

    대신에

    delete from member

    이라는 쿼리로 날아간다면, 어차피 차이가 없는 것이 아닌가요?

    동적쿼리를 잘못 사용했을 경우의 문제일 수는 있겠지만,
    where 1=1을 사용했기에 생기는 문제는 아니라고 생각합니다.
    0
  • 지아빠
    1k
    2014-05-20 14:30:37
    //Terry
    그럼 이것을 애기하는건가요

    select myid, mypasswd, myname
    from member
    where 1=1
    if (memid != null)
    and memid= :memid

    select myid, mypasswd, myname
    from member
    if (memid != null)
    where memid= :memid

    이 경우 memid에 값이 들어 오던 안들어오던 결과가 다른건가요?
    저는 같은 것이라고 보입니다.

    delete 같은 경우 저렇게 짜는것 자체가 1=1 넣고 넣고 상관없이 위험한 것이라고 생각되고요
    0
  • 어쩌다
    3k
    2014-05-20 14:31:39
    앵 이건 말이 안된다 봅니다...

    delete 에 where절이 없이 delete문을 날리는것도 말이 안되지만...
    1=1이 있으나 그게 없으나 실수를 했다면 둘다 마찬가지인거죠.....

    1=1을 사용한다 그래서 잠재적 버그라뇨...
    0
  • 어쩌다
    3k
    2014-05-20 14:34:26
    솔직히 where 1=1 을 ibatis에 사용하는 이유는..
    다음에 나오는 and조건절을 쉽게 만들기 위해서죠...

    만약 where 1=1 를 사용안한다고해서...

    쿠ㅓ리에 where 만 적어 놓는다..?

    아니죠 where절도 다이나믹으로 만들어야 정상인거죠...
    그러므로 where 만 사용하더라도 님이 말하는 오류는 1=1을 사용하든 안하든 일어날수 있는 오류입니다,
    0
  • 레버리지
    2k
    2014-05-20 14:35:36
    1 = 1만 사용 되었다는것은 업무적으로 전체 조회일수도 있는것이고
    , 전체 삭제일수도 있는것으로 보입니다. 1 = 1 이 버그를 양산한다는 것에는 공감이 가질 않습니다.

    0
  • ghrod
    1k
    2014-05-20 14:36:30
    일단 위에 예를 든 경우는 memid 와 같은 꼭 필요한 값의 경우
    1=1을 앞에 잡아서 사용하시는 분들은 당연히 없을 것이고...
    if 또한 잡을 필요가 없죠...필수 값 이니까요.
    1=1을 쓰는 경우는 하위 and 조건이 더 안붙어도 문제가 없는
    쿼리에만 사용을 하게되지요.

    0
  • 레버리지
    2k
    2014-05-20 14:38:05
    만에 하나 개발자가 꼭 넣어줘야 하는 필드값인데 null 을 넣었다면 문제가 될수도 있겠습니다.

    이것은 1=1의 문제가 아니라 Dynamic Query 의 문제를 얘기하고 싶은거 같습니다.
    0
  • ghrod
    1k
    2014-05-20 14:41:56
    고로 레버리지님 말씀대로 전체 삭제 기능을 원하는 경우가 아니고서는...
    delete from member
    where memid='terry'
    (여기서 부터 동적) and ...
    이렇게 구현하지
    이런 필수값이 필요한 쿼리에 1=1은 당연히 안쓰는 부분이지요.
    0
  • ghrod
    1k
    2014-05-20 14:43:00
    고로 제 의견은 1=1 문제없다 입니다^^;
    0
  • 제타건담
    5k
    2014-05-20 14:49:12
    포커스를요..이렇게 맞춰주셨음 하네요..
    다이나믹 쿼리를 만들때 조건절이 반드시 있다..라는 것은 다 아시고 작업을 하실껍니다..
    삭제도 예를 들면 where문이 반드시 있고..거기에 동적 컬럼으로 값이 제어된다면 반드시 where문 다음에 동적 컬럼만 들어가게 하시면 됩니다..
    설사 내가 코딩을 잘못해서 where문만 있고 뒤에 아무것도 없는 상황이 나온다면 그땐 실행을 안해서 데이터가 손상을 입지는 않게 됩니다..
    그러나 where문을 반드시 나오게끔 하기위해 1=1을 사용하시지는 말라는 얘길 하는겁니다..
    where 문을 반드시 나오게끔 하기 위한 방법이 1=1만 있는건 아닙니다..
    처음에 컬럼문쪽 조건을 먼저 만들고 where를 맨 나중에 붙여도 됩니다..

    대강 이런식이죠..

    String query = "delete from member"
    String condtion = null;
    if (id != null){
    condition = "id='" + id + ' ";

    }

    condition = "where " + condition;
    query = query + condition;

    이렇게 하면 1=1이 없어도 where문은 반드시 들어갑니다..

    핵심은..동적컬럼에 대한 제어를 1=1로 하지는 말라는거에요..충분히 이와 같은 방법으로 where문 제어는 가능합니다..
    0
  • ice
    645
    2014-05-20 14:54:44
    개발자 99.9%가 terry님이 이야기 하신 실수를 안하고 0.1%라도
    언젠가는 하게 될지 모를 잠재적 위험요소라면 안하는게 방법적으로는 맞는게 아닐까요??
    1=1 쓰는게 이게 옮다가 아니라 이렇게 하면 단지 개발하는데 편해서가 아닌가요??
    다이나믹 쿼리를 쓰는게 어려운건 아닐텐데 말이죠
    0
  • junya0803
    253
    2014-05-20 14:55:52
    레버리지, 명견시바님 말씀대로 제 생각에도 이 문제는 where 1=1 의 문제이기라기 보다는 동적 쿼리 생성의 문제인 것 같네요.

    다만, where 1=1 의 사용은 select 절에서만 사용하되 전체 검색이 포함된 곳에서 사용하는 것이 바람직하다 생각되네요.
    0
  • 제타건담
    5k
    2014-05-20 14:59:40
    그리고 또 한가지..delete에서 where 문에 1=1을 누가 넣겠느냐..고 이렇게 반문하시는 분들..
    이런 분들은 그나마 낫습니다..적어도 이런 실수를 해서 문제를 일으키지는 않을테니까요..
    적어도 select에서는 이로 인해 버그가 발생되어 검색 시간이 오래 걸릴수는 있으나 데이터가 망가지는 오류는 없을테니까요..

    그러나 사람은 습관의 동물입니다..내가 select문에서 동적 쿼리를 이렇게 해서 해결을 했으니 delete에서도 이렇게 하면 될꺼야..란 생각을 전혀 안할수 있을까요? 습관을 그렇게 들이면 아무 생각 없이 쓰는겁니다..그것이 select냐 update냐 delete냐 이런건 중요한게 아니죠..
    그리고 오동작이 발생하고 나서야 그때서야 깨닫는겁니다..

    애초에 습관을 1=1을 들이지 않고 코딩을 하면 저런 실수를 사전에 안하게 되는겁니다..
    0
  • junya0803
    253
    2014-05-20 15:01:01
    얼음 // 위험요소라면 안하는 것도 중요하고 개발하는데 편한 것도 중요하죠.
    독도 잘 사용하면 약이 됩니다. 위험하지 않고 편하게 사용하는 게 중요하겠죠.
    만약 PL 이라면 이러한 부분의 위험요소를 애초에 차단하기 위해 못쓰게 할 수도 있을 것 같지만
    반드시 모두가 이걸 쓰면 안 된다는 아닐 거라 생각됩니다.
    0
  • tempman
    4
    2014-05-20 15:02:02
    바라보는 관점의 차이 때문에 오해가 있는 듯 합니다.
    where 1=1 구문은 binding 변수를 이용하지 않고 프로그램에서 문자열을 이용하여
    조건절을 조립할 때, 소스를 조금이라도 줄이고자 하는 목적에서 주로 사용합니다.

    1) 모든 조건을 가져오기 위해서 where 구문 사용이 필요없게 되는 경우도 대응하고,
    2) where 다음에 and 키워드가 바로 나오는 것을 체크하는 번거로움도 해소됩니다.

    where 1=1 구문은 쿼리 성능에는 영향을 주지 않습니다만 실제로 권장하지도 않습니다.

    자바와 같이 binding 변수를 이용하여 PreparedStatement와 같은 구문을 사용할 수 있다면
    이와 같은 방법을 이용하시고, 지원이 불가한 언어를 사용하신다면 조금은 지저분하더라도
    프로그램에서 조치하시길 권장합니다.

    편의성을 우선시한다면 where 1=1 구문이 좋을 수도 있겠습니다만 단편적으로는 글쓴이가
    말씀하신대로 데이터 전건 접근을 고려한 것이 아니라면 부작용이 있을 수 있습니다.

    보다 근본적인 관점에서 생각하자면 SQL 구문은 비즈니스 논리에서 접근해야 하는데,
    단지 프로그램의 라인수를 줄이고자 불필요한 구문이 SQL 문장에 삽입되었기 때문에
    설계나 구현 관점에서 보면 그리 좋아보이지도 않습니다.
    0
  • 제타건담
    5k
    2014-05-20 15:12:34
    사람마다..생각의 차이는 있겠지만..제가 말씀드리고픈 의도는..
    자기가 만든 쿼리에 1=1이란 구문을 사용한 곳이 전혀 없으면..
    버그가 발생한다 해도 추적이 용이하다는 겁니다..
    왜냐면 조건문이 비정상적으로 만들어지면 화면 오류 등의 오류로 발생하기 때문에 원인 파악이 쉽습니다..
    그러나 1=1 조건이 들어가면 화면에서는 정상적으로 보일수는 있어도 실제로는 비정상적으로 동작하는 경우가 있기 때문에..
    막상 버그가 발생할 경우 찾기 힘들어지는 상황이 나옵니다..
    지금 당장은 1=1이 여러분들이 코딩하시기 편할겁니다..
    그러나 내가 만든 프로그램이 운영이 되고 또 내가 만든 프로그램이 버그는 100% 없을수는 없다는 전제하에 움직일경우..적어도 버그 추적은 쉬워야 하지 않겠습니까?
    화면에 오류화면으로 나타나질 않아서 오류가 없다..라고 판단할수는 없다는겁니다..페이징 하는 게시판조차 검색 조건을 주었을때 검색 결과가 1만건이 나왔는데..1만건 전부를 조사할수는 없잖습니까?
    적어도 1만건이 정확한 결과로 나올수 있게끔 쿼리상의 오류가 발생할 여지는 없애자는 얘기를 하는겁니다..그걸 넣지 않아도 충분히 동적 쿼리는 만들수 있는거니까요..
    0
  • trazent
    836
    2014-05-20 15:22:53
    이런글.. 너무 좋습니다 ^^
    0
  • 레버리지
    2k
    2014-05-20 15:23:26
    1 = 1 이전에 제가 DBA라면 동적 SQL을 자제 하도록 하고 싶네요 ㅎㅎ
    0
  • vsanv614
    -661
    2014-05-20 15:25:41
    예를 들어 사용자가 뭐가 안된다고 했을 때 개발자가 테스트를 해 보았는데 정상적으로 되었음. 쿼리에러도 안뜨고 도대체 왜 안된다고하는건지 모르겠음. 나는 되는데. .. 계속 고민하고 있음. ...
    사용자 쪽에서 입력 했을 때 NULL값이 들어가서 안되었음. 근데 에러문구가 안나옴. 이건 어떻할 건가요 .. 이런 경험을 해 본 적이 없으나;;;
    0
  • 레버리지
    2k
    2014-05-20 15:27:51
    s87419 // 설명이 어려브요~ ㅋ
    0
  • junya0803
    253
    2014-05-20 15:33:06
    애초에 where 1=1 을 사용하는 습관을 들이지 말자는 의견에는 공감합니다.^^
    그리고 여담으로 동적 쿼리 자체가 버그를 양산할 위험이 크므로 상당히 조심해야 하는 걸로 알고 있어요.
    0
  • fx
    977
    2014-05-20 15:33:47
    Terry 님의 의견을 좀 긍정적으로 생각해보려고 해보았지만,
    where 1=1 에 의한 버그 가능성은 납득하기 어렵습니다.

    물론 주장하시는 버그를 줄이려는 노력은 중요하다고 생각합니다.

    하지만 기술적으로 보면 where 1=1은 결국 없는것과 차이가 없습니다.
    where 1=1을 사용하였기에 한 실수라면, 사용하지 않아도 같은 실수를 할 수 있습니다.

    기술적으로는 문제가 없어도, 습관적으로 where 1=1을 사용하다보면,
    delete 에도 사용하는 실수를 범함 수도 있다는 의견에는 주의를 기울여야 할 것 같습니다.


    저도 애초에 데이터 조작문에는 다이나믹 쿼리를 사용하지 않습니다.
    기본키만으로 갱신, 삭제함을 원칙으로 하지요.
    0
  • vsanv614
    -661
    2014-05-20 15:36:55
    저장프로시저 쓰면 끝
    0
  • junya0803
    253
    2014-05-20 15:39:29
    s87419 // MSSQL 은 그렇지만 Oracle 에서도 Procedure 로 Select 가 되나요?
    0
  • zepinos
    16k
    2014-05-20 15:41:03
    이 내용으론...제가 처음 보는 것이라...살짝 끼어든다면,

    잠재적 버그...라는 단어에 있어서 좀 거부감이 드네요.

    예를 들어 delete 구문을 쿼리툴에서(요즘은 MySQL Workbench 을 씁니다) 직접 실행할 때가 있습니다. 이 때, delete ... from ... 까지만 쓰고 실행해서 대형참사가 벌어지는걸 막기 위해 where 부터 작성한 뒤 앞에 delete from 을 적는게 좋다고 말하는 개발자들이 있습니다.

    네...참 좋은 팁(Tip) 입니다. 특히나 초보자들에겐 적극적으로 권합니다.

    그런데요...이건 팁(Tip) 입니다.

    논리적인 미스로 버그가 발생하는 것이 잠재적인 버그로 이어질 수 있다...는 건 비약이라고 생각합니다. 제가 볼 땐 제가 든 예나 위의 where 1=1 이나 대동소이한 버그라는 것이죠. 실제 현업에서, 특히 운영서버를 직접 건드린지 5년 이상 된 분 중에 where 먼저 적으시는 분 계신가요? 없으실 겁니다.

    where 1=1 없이 프로그래밍 하기 힘든 조건도 있습니다. 그럴 땐 써야죠. 그런데, 주의하자도 아니고...잠재적 버그라고 해버리시면...그것도 곤란하다고 생각합니다.
    0
  • zepinos
    16k
    2014-05-20 15:42:12
    그리고 MyBatis 3 에는 <where> 가 있습니다. 그걸 이용하는 것도 방법이긴 하지만, 개발자의 논리적 실수로 이후 조건이 안나올 경우 대참사가 벌어지는건 동일합니다.
    0
  • 지아빠
    1k
    2014-05-20 16:04:50
    //zepinos
    동의합니다.
    잠재적 위험이란건 논리적으로 프로그램을 잘못 구현되었을때 발생하는거지
    1 = 1 자체를 사용하므로써 발생하는건 아니라고 생각이 되내요

    //Function
    말씀에 동의합니다.

    //Terry
    1 =1 이 잠재적 위험이 있다는 경우가 언제 인지 설명해주실수 있으신가요?
    제가 생각하는 논리로 따져도 설명이 안됩니다.
    0
  • 상상초월
    256
    2014-05-20 16:05:51
    대한민국 상위 1% 개발자 입장으로 말씀드리지요.

    1 = 1 사용은 추천할만 합니다.

    https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1145139539037

    거성 톰아저씨가 가이드 해주시네요. 무려 10년 전부터..

    글쓰신분은.. 참.. 위에서 나온 개발자 실수는.. 정말 생각이 없거나.. 정말 이제 막 일을 시작했거나..

    그런 케이스라.. 딱히 거론하고 싶지 않네요.
    0
  • 지아빠
    1k
    2014-05-20 16:09:23
    //준야
    동적쿼리는 사용하지 않는게 성능상 또는 인덱스 사용에 있어서 좋겠지만
    실제 개발시 반드시 사용할 수 밖에 없는 상황이 더 많습니다.

    버그를 양산시키는 이유는 비즈니스 논리라든가 기타 논리가 들어가야하기?문에
    프로그램 구현시 발생하는 경우지 1 = 1이 발생 시키는것은 아닙니다.

    1 = 1 을 사용시 오히려 논리가 복잡하지 않고 더 간결해지기 때문에 오히려 동적쿼리 프로그램시
    버그를 줄일 수 있습니다.
    0
  • 몽달이
    1k
    2014-05-20 16:16:40
    재미 있네요 ㅎㅎ 제 개인적인 생각을 말씀드리면

    1. select (1행 이상 조회)
    -> where 1=1 (사용 가능)

    2. select (1행 조회)
    -> where 1=1 (권장안함)

    3. delete, update
    -> where 1=1 (권장안함)

    * pk나 unique키가 있는 값들에 대하여 where 1=1을 사용 안하면 될듯합니다.

    개인적인 생각입니다.

    0
  • 뒷집할머니
    980
    2014-05-20 16:41:11
    1=1 을 사용하지 않으면 매번 and를 넣을 것인가 말 것인가 판단해야하는데,
    그거보다 그냥 처음에 조건이 하나라도 입력되었나 안 되었나 판단하고
    편하게 하는게 나아 보이네요.
    0
  • 내사랑내곁에
    279
    2014-05-20 16:48:26
    다이나믹쿼리자체를 쓰는게 문제이지 1=1을 쓰는게 문제인가요?
    뭐 워낙 툴이 좋으니 요즘엔 안그렇지만 문자열로 쿼리를 만들어내는 다이나믹쿼리를 쓴다면 똑같은 위험성이 존재하니까요.

    왜 1=1의 문제로 접근하는지 모르겟습니다.
    다이나믹쿼리를 할때의 기술적 방법론을 거론해야지 맞는듯하네요.
    0
  • 제타건담
    5k
    2014-05-20 17:00:43
    저는 다이나믹 쿼리가 문제가 있다고 생각하진 않습니다..정말 다이나믹 쿼리 외엔 방법이 없으면 써야 하는게 맞죠..
    다만 다이나믹 쿼리 만들때 1=1은 사용하지 말자는 겁니다..
    그리고 잠재적 버그..라는 단어 선택에 대해 그건 아니라고 생각하시는 분들에게 저는 되물어보고 싶네요..
    이제껏 제가 길게 설명했던 예들이 있으니 더는 예를 들어드리지 않겠습니다..
    그게 의도적이든 의도적이지 않든 버그..라는 것에는 다들 동의하실겁니다..버그가 아니라고 하시는 분들에게는 할말 없습니다..
    그럼 잠재적..이라는 의미는 뭘까요?
    내가 인지하고 있었다면 결코 잠재적..이라 할수는 없습니다..내가 인지하고 있었지만 그걸 고치지 않았다면 그건 본인이 버그 막기 노력을 안한거지 잠재적이어서 못막았다..라고 할수는 없는겁니다..
    또한 이것은 정상적인 데이터 흐름에서 발생하는 상황도 아닙니다..
    전혀 의도하지 않은..예를 들어 내가 개발한 Spring Servlet Context에 다른 사람이 추가로 개발한 Servlet Context가 붙으면서 그 사람이 null 체크를 소홀히 했고..나는 내가 null 체크를 확실히 했으니 내가 만든 Spring Root Context의 Repository부분에서 쿼리 만드는 시점에서는 따로 안해도 된..그런 상황에서는 분명 잠재적인 버그 요인이라 말할수 있는겁니다..
    자꾸 잠재적..이라는 것에 거부감을 가지시는데..본인이 한 환경하에서만 생각하시지 마시구요..
    내가 만들어놓은 환경에 다른 환경이 추가로 붙으면서 그 환경에서 나와 똑같은 가이드로 진행하지 않았을 경우도 따져보시라는 겁니다..
    물론 그런 경우까지는 오버라고 할수 있겠죠..그 사람이 어떻게 할지는 모르는거니까요..그러나 모르기 땜에 내가 할수 있는한 최선의 선에서까지는 다 막아보자는 얘길 하는겁니다..
    0
  • 내사랑내곁에
    279
    2014-05-20 17:03:19
    void test(String name){
    if("test".equals(name)){
    addTable();
    }
    }

    글쓰신분의 논리로 보자면
    if("test".equals(name)) 라고 쓰면 안됩니다.
    if(name.equals("test")) 라고 써야겟죠.
    왜냐하면 개발자가 name의 null체크를 안할가능성이 있기에 체크를 안햇는데도 프로그램이 진행되는것을 막기 위해서겟지요..
    이게 맞나요?
    0
  • 제타건담
    5k
    2014-05-20 17:07:01
    그리고 누차 얘기드리지만..저는 1=1이 DB 퍼포먼스에 영향을 줘서 문제가 있다고 말씀 드린게 아닙니다..윗분이 asktom 얘기를 했지만..asktom의 관점은 DB에서의 퍼포먼스 관점에서 본 것이지 전체적인 코딩 맥락에서 본게 아닙니다..최종 쿼리가 어떻게 만들어지며..그 쿼리가 어떤 결과를 일으키는지를 얘기하는겁니다..초보자가 일으키는 실수..좋습니다..그러면 그런 초보자가 일으키는 실수라 치부하며 님은 그런 초보자가 일으키는 실수를 매번 딱가리나 하며 보내실껀가요?
    쓰면 안된다고 했을땐 이러이러해서 안된다..라고 해줘야 하는게 맞는겁니다..자꾸 DB 퍼포먼스로 얘기하시지 마시고..최종 쿼리문이 어떻게 만들어지는지..그로 인해 결과물이 어떻게 나오는지를 관점으로 보세요..
    그 관점에서 보면 select 문에서도 사용해서는 안됩니다..그 이유에 대한 예시는 제가 위의 댓글에서 order by 예로 언급드린게 있습니다..
    0
  • 제타건담
    5k
    2014-05-20 17:13:56
    // 천회장
    and는 처리하기가 쉽습니다..
    조건절을 동적으로 다 만든뒤에 최종 조건문이 and로 시작하면 그 and를 제거한 substring을 만들고..
    그것을 where와 합치면 됩니다..

    String wherestr;
    if(name !=null){
    wherestr += 'and name='" + name + "' ";
    }
    if(id != null){
    wherestr += 'and id='" + id + "' ";
    }

    wherestr.substring(0,4); // and 제거
    wherestr = "where " + wherestr;

    이렇게 하면 처음 and는 제거 됩니다..
    0
  • 제타건담
    5k
    2014-05-20 17:19:40
    //skedys1
    그건 null 체크의 방법이 잘못된거지 null체크를 안했다고 말할수는 없습니다.."test".equals(test);로 해야하는걸 test.equals("test");로 했다고 null 체크를 안했다고 할수는 없습니다..방법이 틀린거죠..
    제 얘기는 아예 그런 if문조차 안했을때의 얘기입니다..
    이런거 안할사람이 누가 있겠냐구요?
    없진 않습니다..
    초보자라서 그렇게 할수 있다구요?
    초보자랑 같이 일 안하시나요?
    남이 저렇게 싸질른 똥을 내가 치울 상황이 올수도 있습니다..
    그럴바엔..어떻게 똥을 싼건지 알수가 없으면 적어도 가이드라인에서 이렇게 똥을 싸라고 맞춰주면 그나마 치우는 방법이 쉽지 않을까요?
    저는 그런 의도로 이 얘기를 하는겁니다..
    0
  • 뒷집할머니
    980
    2014-05-20 18:15:51
    Terry //
    님 말씀대로 하면 id, name 둘 다 null일 때
    쿼리구문에서 에러가 발생합니다.
    0
  • m1d2h3
    913
    2014-05-20 19:00:04
    동의할수없네요~쓰기나름이고 생각하기나름입니다. 전다이나믹쿼리자체를 왠만하면배제하구요 다이나믹부분은최소화합니다.
    0
  • 하늬바람
    480
    2014-05-20 22:23:35
    평소 존경하는 Terry님이라 감히 말씀드리기가 조심스럽군요.

    WHERE 1 = 1은 실행계획에 전혀 문제가 되질 않을 것 같습니다.

    DB Optimizer가 워낙 똑똑하기 때문입니다.

    더구나 천회장님이 얘기하신 것처럼 A is null과 A = null은 전혀 다르기도 하구요.

    그럼 Dynamic SQL로 귀결되는데 이걸 안 쓸 수도 없을 뿐더러 안쓴다면 WHERE 1 = 1은

    이미 논쟁의 대상이 아니기 때문에 이 문제로 Dynamic을 쓸건지 말건지는 논제에서

    좀 벋어나는 걸로 생각됩니다.

    Dynamic의 문제라고 한다면 pre-compile의 문제가 되는데 옛날 얘기로 여겨집니다

    (훌륭한 프로그래머의 결벽증으로 생각합니다만...).

    워낙 machine이 좋아졌을 뿐더러 아키텍쳐적인 관점에서 balance를 생각해 볼 필요도

    있을 것 같습니다. WHERE 1 =1 은 이후의 조건절이 없다는 것을 상정한 것인데

    Dynamic SQL을 배제한다면 상대적으로 그만한 Static을 처리하기 위한 프로세스의

    구현을 배제할 수 없습니다.

    비용적인 측면에서 비교 대상이 되질 않는 것 같군요.

    현대적인 관점에서 DB는 구축보다 이를 어떻게 이용하는냐가 갈수록 더욱 중요해지는

    것 같습니다. DB 이용의 관점은 시대적인 트렌드도 빠르게 많이 변하구요.

    기록은 여전히 6하 원칙이면 문제가 없는 것 같군요.

    당연한 귀결로서 DB에서 어떻게 내가 원하는 것을 찾는가 하는 것은 변화가 쉽게 일어날

    것 같습니다. 이것은 WHERE 조건절이 쉽게 변할 수 있고 pre-compil에 대한 비용보다는

    WEERE 조건절을 static하게 가져가는 비용이 훨씬 크다고 볼 수 있겠습니다.

    이런 이유로 감히 WHERE 1 =1 은 문제가 없다는 쪽에 한표를 던져봅니다.
    0
  • 하늬바람
    480
    2014-05-20 22:41:54
    잘못된 코드의 실행 방지가 WHERE 1 = 1의 사용제한으로 확보되지는 않을 것 같습니다.

    delete from where 1 = 1; 이 실행되지 말아야 했다면 그것은 잘못된 코드일 뿐입니다.

    관련된 link 하나 걸어봅니다.

    http://www.zdnet.co.kr/column/column_view.asp?artice_id=201311180939135
    0
  • fx
    977
    2014-05-20 23:05:37
    천회장님의 덧글을 보니, Terry님이 말하고자 하는 의미를 조금 알겠습니다.

    만약 SQL문에 10개의 옵션조건만 있지만, 모든 조건이 생략되었을 경우 어떤 처리를 할 것이냐?

    그것은 상황에 따라 다릅니다.

    무조건으로 간주하고 조건없이 모든 집합을 대상으로 할 수도 있고,
    각각은 비록 옵션이지만, 하나라도 없는 경우는 예외로 할 수도 있죠.

    제 경험상은 전자가 훨씬 더 많습니다만, 어째든,

    where 1=1은 전자일 경우, 편리하게 처리하고자 사용하는 방법입니다.
    후자일때면 1=1을 붙이지 않고 처리하면 되죠.

    1=1을 사용하지 않더라도, 업무상 전자와 후자는 다이나믹 코드를 작성할때 서로 다르게 작성해야 합니다.

    1=1을 넣어야 할때와 그렇치 않을 때를 실수한다면,
    마찬가지로 1=1을 사용하지 않더라도 where를 넣고 뺌을 실수 할 수 있습니다.

    SQL문 입장에서 보면 where 1=1 은 어떠한 로직 변경도 없습니다. 생략했을 때와 동일합니다.
    비록 몇자 더 타이핑 한다는 점을 제외한다면 말이죠.

    반대로 where 1=1 을 사용하지 않는다면, 전자를 처리하기 하기 위해서는 조건이 없을때 where 까지 제거하는 로직을 추가하여야 합니다.
    이것은 몇자 더 타이핑 한 것보다 손이 더 많이가죠. 그것은 잠재적 버그가 나올 가능성이 오히려 더 증가하는 일이라 봅니다.


    자 제목을 조금만 수정하면 될것 같습니다.

    모든 옵션 조건이 생략되었을 때, 예외가 발생하여야 하는 다이나믹 쿼리에서
    where 1=1 을 사용하면 안된다...

    너무 당연한 이야기라. 이런 팁일꺼라 예상하지 못하였습니다.

    제 생각은
    모든 옵션 조건이 생략되었을 경우, 전체 집합이 처리되는 다이나믹 쿼리에는
    where 1=1 을 쓰는 것이 간단하다.






    0
  • 하늬바람
    480
    2014-05-20 23:27:10
    ㅎㅎㅎ. Function님 감탄이 절로 나오는군요. 큰 깨달음이 있었습니다. 감사합니다.
    0
  • chela
    3k
    2014-05-20 23:32:07
    where 로 쓰나 where 1=1 로 쓰나, 그건 1=1 의 문제는 아니라고 봅니다.

    where 만 쓰는 경우 어떻게 위의 문제를 방지 하시나요 ?

    방법을 떠 올리셨죠 ?

    그럼 그 방법을 where 1=1 에도 똑같이 적어 주시면 됩니다.

    별로 논란 거리는 아닌거 같네요.

    그리고 Java 에서만 쓰는게 아니고 php, asp 하시는 분들도

    많이들 쓰는 방법입니다.

    delete 에서 key 가 null 인 경우 전건을 삭제하는 건 일일히 모든 쿼리에서 걸어줄게 아니고, 공통에서 delete 인 경우 key value 가 null 로 오면 에러가 나도록 java 단에서 잡아주는게 (무조건 해야죠 이런건) 맞습니다.
    0
  • butnim
    2k
    2014-05-21 02:34:20
    그런거 신경쓰지 마십쇼
    플젝 결과물 품질에 영향이 별로 없습니다
    0
  • seong79
    167
    2014-05-28 23:49:34
    흠..
    논외이겠지만..
    java라서preparedstatment.라서..
    where 1 = 1이 sqlinjection 타겟이 되므로 사용하면 안된다는.. 고려할 문제 아닌거죠????
    0
  • daknichu
    7
    2015-04-09 17:23:28

    즐거운 토론이네요 댓글까지 하나하나 다 읽어 보았습니다.

    그냥 하지 말래서 안하는 거였는데 다시한번 생각해보게 되네요.

    0
  • 거침없는녀석
    4
    2015-05-08 20:35:50

    많이 늦은 의견을 드리고 자 합니다.

    WHERE 절에서 [Column] = null 은 참일까요 거짓일까요?

    정답은 거짓입니다. 일부 DBMS에서는 쿼리 파싱 과정에서 오류로 판단하게 됩니다.


    대표적인 DBMS의 경우 조건절 처리시 참이 아닌 이외의 모든 상태를 거짓으로 처리하게 됩니다.

    따라서 해당 조건이 없어지는 것이 아니라 거짓이라는 조건으로 남아있기 때문에

    생각하신대로 쿼리가 처리되는 것이 아닌

    참 and 거짓 (and 거짓 <- 거짓이 나왔기 때문에 and 조건문 상 옵티마이져에 의해 제거됨)

    으로  처리가 됩니다.


    따라서 동적 조건절 작성을 위해 1=1 사용엔 큰 무리는 없습니다. 해당 1=1 또한 파싱 과정에서 참이라는

    결과 값만을 가지고 쿼리를 수행하게 되는 것이지요~


    0
  • 실버나이트
    2
    2015-09-14 14:34:31

    저 혼자 일할때는 몰랐는데 부사수나 경험이 별로 없는 개발자들과 같이 일하면

    제 소스를 보고 복붙하기때문에 코딩이 좀 더 조심스러워지긴 합니다.

    기술적으로 이건 이래서 이렇게 쓰면 안되고 저렇게 다 체크해줘야 한다..

    다 알려줄 수 있다면 좋은데 항상 그렇지는 못하니까요 ㅎ

    원천적으로 막을 수 있는건 막아야죠 특히 DB 스키마와 관련된건..

    이렇게 저렇게 코딩하면 되는데 왜 쓰면 안되냐

    물론 모두가 다 그렇게 알고쓰면 좋은데 말했듯이..그렇지는 못하니까요 ㅎ

    그런 말씀을 하시려는게 아니었나 생각해서 한자 적어봅니다.

    0
  • 바다21
    90
    2016-04-22 21:53:06

    흠... 여기 글들이 참.. 본인이 개발했던 경험이 모두 정답은 아니라는 것...

    그냥 이런저런 의견이 있으면. 아~ 이럴 땐 이럴 수도 있겠구나~ 하는 점..

    본인이 DBA 면 동적쿼리를 자제시키고 싶다니..  위험한 분도 계시고... 

    대체로 SI 하시는 분들일텐데.. SI하면서 가장 큰 악재는 본인이 꼰대가 되버리는겁니다.

    개발자가 꼰대라뇨! (물로 스스로는 자기가 꼰대인지 모릅니다.)

    상황에 맞게 최고의 솔루션을 찾아내는게 SI의 묘미가 아닐런지..

    여튼.. 도메인 전문가는 우대해주는게 맞는데, 그게 기술적 성숙도와 동일한건 아니라는 점만 깨닫고 살았으면 좋겠습니다. (저를 포함하여..)


    한참 지난 떡밥같지만..

    저는 WHERE 1=1 반대입니다. 에러가 나는 상황에선 에러가 나는게 맞습니다. 시스템도.. 사람이 아픈거 참고 살다가 암걸리고 하는거랑 비슷해요. 문제가 있는 상황에선 문제를 뱉어주는게 맞습니다. (나도 꼰대인가? ㅋㅋ) 나몰라라 식의 1 = 1 쿼리보다는 prefix 조정하는 코드를 넣어주는 것만으로도 의미가 있지 않을까.

    0
  • 훈훈
    311
    2016-09-05 02:43:28

    where 1=1 and name = 'terry' 여기서 name = null이라면 where 조건은 false 인것 아닌가요?

    where 1=1 을 왜 써야 하는지 모르는 상황이지만 저도 저런 상황에서는 안써야 한다 라고 생각하고 있고

    where name = 'terry'; 라고 쓰기만 하면 될거같은데 어렵군요

    0
  • iDontKnow
    3
    2017-07-28 18:47:29

    지나가던 나그네인데 뭔가 하고 봤더니 전혀 엉뚱한 내용을 글쓴이가 써놓은 듯한 기분이 들어 몇글자 남깁니다.

    한개의 회원행에 대해서 예를 들어놓았지만 전혀 와닿지 않네요. 


    어짜피 둘다 널이면 where 1 = 1을 쓰나 안쓰나 동일하게 여러건 나옵니다.

    예가 잘못됐기 떄문에 이 글은 처음부터 끝까지 똥글이 됩니다.

    애초에 논란의 글을 쓰기 위해선 많은 생각을 하거나 정확한 논리가 있어야 합니다.

    그런데 예제부터 문제가 있다면 글쓴이 주장이 이미 바닥을 들어낸겁니다.

    예제 하나 잘못했다고 이렇게 댓글을 다는게 너무 한거 아니냐고 말씀하실까봐 한가지 더 얘기를 드리면 


    delete의 경우 어떤 멍청한사람이 where 1=1을 쓰나요? 아니 delete문에 where 1 = 1을 쓰는 이유가 있나요?

    만약 쓰게 된다면 설계가 잘못된겁니다. 이건 애초에 '잘못된 설계에 대한 거기에 적합한 예제'이기 때문에 예로 적합할 수 없습니다. delete 및 update는 본디 unique key가 필수로 최소 1개의 column이 들어가기 때문에 where 1 = 1을 절대로 쓸일이 없는거예요 


    그냥 본인이 생각한거에 사로잡혀서 무조건 맞다고 생각하고 있기 때문에 이상한 예를 들고 물고 늘어지는걸로 밖에 보이지 않습니다.


    쓸데 없는 논제에 없는 논리 붙여가면 글써봐야 어그로밖에 되지 않습니다.

    1
  • isp8373
    2
    2017-11-29 21:41:51 작성 2017-11-29 21:42:56 수정됨

    고수님들의 썰전 초보가  낄수가 없네요^^ 

    0
  • jontama
    149
    2018-01-26 12:20:46 작성 2018-01-26 12:21:23 수정됨

    delete from member
    where 1=1
    and memid='terry' -- memid 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..
    and name='Terry' -- name 값을 입력받아 조회할 경우 이 조건행이 추가되겠죠..

    마찬가지로 어떤 이유에선지 memid와 name 모두 null로 들어왔다면 최종 만들어지는 sql문은 다음과 같이 될껍니다..
    delete from member
    where 1=1


    -------------------------------------


    이렇게 실행될꺼 같은데요?

    delete from member
    where 1=1
    and memid=null
    and name=null


    아닌가??

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.