나는 SO에 대한 SQL 질문에 대답하는 데 많은 시간을 소비합니다. 나는 종종이 ilk에 대한 쿼리를 보게된다.
SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017'
SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01'
SELECT * FROM person WHERE birthdate BETWEEN 'some string' AND 'other string'
즉, 주어진 매개 변수의 문자열에서 날짜로의 암시 적 변환 (나쁜) 또는 x 백만 개의 데이터베이스 행 값을 문자열로 변환하고 문자열 비교 (걱정)를 수행하는 데이터베이스에 의존
나는 때로는 똑똑한 답변을 작성하지만 실제로 데이터 유형으로 덜 조잡하거나 문자열로 타이핑해야한다고 생각하는 높은 rep 사용자 인 경우 종종 의견을 남깁니다.
주석은 일반적으로 to_date (Oracle), str_to_date (MySQL), convert (SQLSERVER) 또는 이와 유사한 메커니즘을 사용하여 문자열을 날짜로 명시 적으로 변환하면 더 좋을 것입니다.
--oracle
SELECT * FROM person WHERE birthdate BETWEEN TO_DATE('20170101', 'YYYYMMDD') AND TO_DATE('20170301', 'YYYYMMDD')
--mysql
SELECT * FROM person WHERE birthdate BETWEEN STR_TO_DATE('20170101', '%Y%m%d') AND STR_TO_DATE('20170301', '%Y%m%d')
--SQLS, ugh; magic numbers
SELECT * FROM person WHERE birthdate BETWEEN CONVERT(datetime, '20170101', 112) AND CONVERT(datetime, '20170301', 112)
그렇게하는 것에 대한 나의 기술적 타당성은 날짜 형식에 대해 명시 적이며 소수의 소스 매개 변수가 확실히 대상 열의 데이터 유형이되도록하는 것입니다. 이렇게하면 데이터베이스가 암시 적 변환 (첫 번째 예의 1 월 3 일 / 1 일 3 월 인수)이 잘못 될 가능성을 방지하고 db가 테이블의 백만 날짜 값을 문자열로 변환하지 못하도록합니다 (일부 서버 별 날짜 사용) 비교를 수행하기 위해 sql 내의 문자열 매개 변수의 날짜 형식과 일치하지 않을 수도있는 형식)
그렇게하는 것에 대한 나의 사회적 / 학술적 정당성은 SO가 학습 사이트라는 것입니다. 그것에 관한 사람들은 암묵적으로 또는 명시 적으로 지식을 습득합니다. 이 질문에 대한 답변으로 초보자를 때리는 방법 :
SELECT * FROM person WHERE birthdate BETWEEN '2017-01-01' AND '2017-03-01'
그들이 바람직한 형식으로 날짜를 조정하여 이것이 합리적이라고 생각하게 만들 수 있습니다.
SELECT * FROM person WHERE birthdate BETWEEN '01/01/2017' AND '01/03/2017'
그들이 날짜를 변환하려는 명백한 시도를 적어도 보았을 경우, 이상한 날짜 형식으로 시작하고 영원한 버그가 발생하기 전에 죽일 수 있습니다. 결국, 나는 (I) 사람들이 SQL 주입 습관에 빠지지 않도록 시도하고 설득하려고합니다 (그리고 @pBirthdate
프런트 엔드에 날짜 시간 유형이있을 때 쿼리를 매개 변수화 한 다음 문자열 인 드라이버에게 선언하는 사람은 누구 입니까?)
추천을 한 후의 상황으로 돌아 가기 : "일반적으로"다른 사람이하는 일 ","항상 나에게 도움이된다 ","일부 매뉴얼 또는 참조 문서 표시 "와 같이"명시 적으로, x 사용 "추천으로 푸시 백을받습니다. 그것은 "명시 적이어야한다"또는 "무엇입니까?"
나는 이들 중 일부에 응답 WHERE age = '99'
하여 연령을 문자열로 전달하여 int 열을 검색할지 여부를 물었습니다 . "어리석게도, 우리는 int을 검색 할 때 '를 넣을 필요가 없다"는 응답이 있기 때문에 어딘가에 다른 데이터 유형에 대한 인식이 있지만 int를 검색하는 논리적 인 도약과는 관련이 없습니다. 문자열을 전달하여 열 (명확하게 어리 석음)과 문자열을 전달하여 날짜 열을 검색하는 것 (겉보기에 합리적인)
따라서 SQL에서 우리는 숫자 (구분 기호없이 숫자 사용), 문자열 문자열 (아포스트로피 구분 기호 사이에 사용)로 쓰는 방법이 있습니다. 왜 날짜에 대한 구분자가 없는가? 대부분의 DB에서 그러한 기본 데이터 유형입니까? 이 모든 것이 자바 스크립트가 /
문자의 양쪽 을 넣어 정규식을 지정할 수있는 것과 같은 방식으로 날짜를 쓰는 방법만으로도 해결할 수 있습니까? /Hello\s+world/
. 데이트 할 것이없는 이유는 무엇입니까?
실제로, 내 지식으로는 (만) Microsoft Access에는 실제로 "이 구분 기호 사이에 날짜가 기록되었습니다"를 나타내는 기호가 있으므로 우리는 좋은 지름길을 얻을 수 WHERE datecolumn = #somedate#
있지만 날짜 표시는 여전히 mm / di vs dd와 같은 문제를 일으킬 수 있습니다. / mm, MS는 항상 VB 군중이 좋은 생각이라고 생각했던 것들로 빠르고 느슨하게 연주했기 때문에
요점으로 돌아가서 :이 매체를 사용하여 명시 적으로 여러 가지 다른 데이터 유형을 문자열로 전달하도록하는 것이 현명하다고 주장합니다.
유효한 어설 션입니까?
이 성전을 계속해야합니까? 문자열로 타이핑하는 것이 현대적인 것이 아니라는 것이 타당합니까? 또는 쿼리를 밀어 넣을 때 모든 RDBMS (고대 버전 포함) WHERE datecolumn = 'string value'
가 문자열을 날짜로 정확하게 변환하고 테이블 데이터를 변환하거나 인덱스 사용을 잃지 않고 검색을 수행합니까? 나는 적어도 Oracle 9의 개인적인 경험으로는 아니오라고 생각합니다. 문자열이 항상 ISO 표준 형식으로 작성되고 열이 날짜 풍미 인 경우 도망가는 시나리오가있을 수도 있습니다. 문자열 매개 변수는 항상 내재적으로 올바르게 변환됩니다. 이것이 제대로됩니까?
가치있는 일입니까?
많은 사람들이 그것을 얻지 못하거나 신경 쓰지 않거나 그들의 int는 int이지만 날짜는 문자열이라는 점에서 위선을 보입니다. 뭐, 당신의 요점에 동의합니다
WHERE age = '0x0F'
데이터베이스가 15 살짜리를 검색 할 수있는 올바른 방법 인지 묻기 위해 예제를 확장하려고 생각 했습니다.
WHERE datecolumn =
1912, 2012, 2001, 1901, 12 또는 1 년을 요청할 수있는 01/02/12 '`에 문제가있는 사람을 보았습니다 . 또한 데이터베이스 세계 외부의 문제이기도합니다."09"
int 로 변환 하는 것이 충돌을 일으키는 이유를 이해할 수없는 프로그래머의 수 는 군단이고, 9는 유효한 8 진수가 아니며 앞의 0은 많은 시스템에서 문자열을 8 진수로 만듭니다