2014-02-22 1 views
2

필자는 광고 된 열에 대해 다양한 SQL 데이터베이스의 기존 테이블에 쿼리를 제출할 수있는 웹 서비스를 작성하고 있습니다. 나는 다음과 같은 자바 코드를 실행 가능한 열 결정된 이름으로SQL 문에서 열 이름을 따옴표로 묶어야하는지 확인하는 방법은 무엇입니까?

CREATE TABLE stpg.test (
    test integer, 
    "Test" integer, 
    "TEST" integer 
); 
insert into stpg.test values (1,2,3); 

:

나는 그렇게 정의 된 PostgreSQL의 테이블이

ResultSet rs = dbmd.getColumns(null, "stpg", "test", null); 
while (rs.next()) { 
    System.out.println(rs.getString("COLUMN_NAME")); 
} 

를 내가 얻을 :

 
test 
Test 
TEST 

사용자가 검색어를 제출하고 반환 된 열을 참조하면과 같이select test, Test, TEST from stpg.test 그는 예상했던 것 대신 1 1 1을 얻을 것입니다. 1 2 3 이것은 버그입니까?

나는 select test, "Test", "TEST" from stpg.test을 수행하면 결과가 올바르게 반환된다는 것을 알고 있습니다. 그러나 사용자는 따옴표로 정의 된 "대문자"열의 값을 가져 오기 위해 쿼리에서 따옴표를 사용해야한다는 것을 알지 못합니다.

따옴표로 이름을보고 할 수 있도록 열 이름이 대소 문자를 구분한다는 것을 알 수있는 방법이 있습니까? 나는 그것을 다른 데이터베이스에 대해 일반적으로 처리해야하므로 JDBC API 접근 방식이 바람직합니다. ResultSetMetaData을 사용하고 getColumnNamegetColumnLabel을 호출했지만 따옴표없이 이름을 반환합니다. isCaseSensitive을 호출하면 항상 false가 반환됩니다.

+2

왜 항상 열 이름을 인용하지 않습니까? – Camilo

+1

이것은 문서화 된 동작입니다 : http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS 및 다른 사람들과 반대로 나는 ** 결코 ** 추천 할 것입니다 ** 따옴표 열 이름 unles 당신이 정말로 의미를 이해합니다. –

+0

나는 그것을 피할 수 있다면 대소 문자를 구분하는 컬럼 이름을 사용하는 것은 나쁜 생각이라고 제안한다. –

답변

3

따옴표로 이름을보고 할 수 있도록 열 이름이 대소 문자를 구분한다는 것을 알 수있는 방법이 있습니까?

대문자가 포함되어 있으면 열 이름을 따옴표로 묶어야한다고 생각하는 것처럼 보입니다. 이 이론에 불과

if (!name.equals(name.toLowercase())) { 
     // needs quoting. 
    } 

:하지만이 경우

  • 그냥 모든 열 이름을 인용하는 경우, 또는
  • 대소 문자를 구분하지 당신이 사용자가 제공 한 열 이름을 치료 합니다.

(대소 문자 구분이 중요한 경우 열 이름을 가진 후자의 시점에 아마입니다 나쁜 디자인. 대소 문자 구분은 확실히 당신이 당신의 웹 사이트의 사용자에 대해 걱정할 필요가 싶어 것이 아닙니다 ...)


나는 ResultSetMetaData에를 사용하고 getColumnName 및 getColumnLabel를 호출하려고하지만 그들은 따옴표없이 이름을 반환합니다.

따옴표는 열 이름의 일부가 아닙니다! 그것들은 식별자 (일반적으로)를위한 (Postgres) SQL 구문의 일부입니다. 이름은 따옴표 안에있는 내용입니다.

isCaseSensitive를 호출하면 항상 false가 반환됩니다.

솔직히 말해서 그 방법의 결과가 의미하는 바는 무엇입니까 (javadoc에서). 그러나 사용중인 JDBC 드라이버에서 버그를 발견했을 수도 있습니다. (아니면 그냥 잘못이다. 그의 코드는 현재 포스트 그레스 의 방법은 열 유형 정보를 참조한다는 것을 구현 ...) 항상 열 이름을 인용에

+0

'if (name.equals (name.toUppercase()))'테스트를 얻지 못했습니다. 올바르게 읽으면 열 이름이 * 완전 * 대문자 인 경우에만 해당됩니다. 그러나 PostgreSQL은 이름에 * * 문자가 대문자이면 인용해야합니다. 그래서 그 테스트는 작동하지 않을 것입니다 ... – exhuma

+0

여기에도 JDBC API에는 결함이 있습니다. 'Connection' 또는'DatabaseMetaData'는'quoteIdentifier' 메쏘드를 노출해야하지만 그렇지 않습니다. 따옴표를 붙이기가 어렵습니다. –

+0

@exhuma - 네 말이 맞아. 곤충. 결정된. –

1

내가 제안했다. 따옴표를 제거 할 이유가 없습니다. 그리고 더 중요한 것은 코드를 인용할지 여부를 결정하는 코드가이 아닌 인 10 ~ 15 행을 넘을 것입니다. 이는 새로운 버그, 오타, 개념 오류를 야기 할 수있는 약 15 줄의 코드입니다.

각 열을 직접 인용하면 언제나 정확합니다!

또한 질문에 대해서는 select test, Test, TEST from stpg.test의 결과가 버그인지 여부 : 그렇지 않습니다. 이것은 PostgreSQL의 기본 동작입니다. 모든 열 이름 (또는 db-object 이름)은 따옴표로 묶은 경우를 제외하고 항상 낮아집니다. 또한 isCaseSensitive으로 연결됩니다. 은 대소 문자를 구분하지 않으므로이므로 항상 거짓입니다.

더 중요한 메모 : 사용자가 SQL 쿼리를 입력하게하면 다른 이상한 문제가 발생할 수 있습니다. 사용자가 어떤 종류의 속임수를 사용하는지 알 수 없습니다. 설계 상 또는 사고로)

사용자가 SQL 쿼리를 입력하도록 허용 한 첫 번째 경우라면주의 깊게 조치 계획을 고려하십시오! 사용자는 오류, 실수 (수백만 행이있는 5 개의 테이블에있는 전체 직교 제품? , 필터 만 적용 ... ... 재미있는 시간 ...)을 입력하거나 DB를 사용하려고 할 수도 있습니다. 이 일을 정말로 결정하면 버클하십시오! :) 그것은 모두 사용자 기반의 기술적 지식에 달려 있습니다.

또한 Postgres에서 모든 것을 소문자로 유지하는 것이 유용하고 사용자는 단어를 구분하기 위해 밑줄을 긋습니다. UserAccount 대신 user_account과 같습니다.

관련 문제