복붙노트

[SQL] SQL에서는 여러 가능한 메뉴 선택을 통해 선택하는 성명을 준비?

SQL

SQL에서는 여러 가능한 메뉴 선택을 통해 선택하는 성명을 준비?

내가 널이 될 수 모두 4 개 메뉴 선택 (제품, 위치, courseType 및 범주), 그래서 (JSF를 사용하여 프로그래밍 만이 SQL 질문이기 때문에 즉,이 질문에 무관해야한다).

메뉴 선택은 사용자가 선택하는 변수 관리 빈을 보내고, 준비된 명령문은 사용자가 (있는 경우)를 선택하는 메뉴에서 정보를 사용하여 데이터베이스 테이블을 검색 사용됩니다.

사용자가 메뉴 항목 널 (null)을 떠나면, 그것은 모든 것을 검색한다.

사용자가 1 또는 2 또는 정보 메뉴 항목, 다른 하나 개는 null의 3 잎 경우, 그에 따라 검색한다.

내 문제는 내가 모든 사람에 대한 적절한 SQL 문에 부착 된 콩의 경우 / 다음 문을 무리없이 이렇게 어떻게인가?

아니면 내가 그이 모든 작업을 수행 할 수있는 하나의 더 나은 SQL 문이있다?

나는 자바에서 준비된 문을 사용하고 있습니다.

나는이 시도 :

if (product != null && location != null && courseType != null && category != null) {
            pstmt = conn.prepareStatement("select * FROM Courses WHERE "
                    + "product = ? "
                    + "and location = ? "
                    + "and courseType = ? "
                    + "and category = ?");

            pstmt.setString(1, product);
            pstmt.setString(2, location);
            pstmt.setString(3, courseType);
            pstmt.setString(4, category);
        } else if (product == null && location != null && courseType != null && category != null) {
            pstmt = conn.prepareStatement("select * FROM Courses WHERE "
                    + "location = ? "
                    + "and courseType = ? "
                    + "and category = ?");


            pstmt.setString(1, location);
            pstmt.setString(2, courseType);
            pstmt.setString(3, category);
        } 

등 등하지만 16 일 존재의 널 (null)의 각각의 경우에 대한 시간이 아니라 다른 사람처럼 이렇게해야? 똑똑한 방법이 있어야합니다 (중 1 SQL 문 또는 몇 자바의 경우 / 다음 문을 사용하여?)

Luiggi 멘도사 업데이트 감사합니다! 내 코드는 다음과 같이 작동합니다 :

pstmt = conn.prepareStatement("select * FROM Courses WHERE " 
         + "(product = ? or ? is null) " 
         + "and (location = ? or ? is null) " 
         + "and (courseType = ? or ? is null)" 
         + "and (category = ? or ? is null)"); 

         pstmt.setString(1, product);
         pstmt.setString(2, product);
         pstmt.setString(3, location);
         pstmt.setString(4, location);
         pstmt.setString(5, courseType);
         pstmt.setString(6, courseType);
         pstmt.setString(7, category);
         pstmt.setString(8, category);


        rset = pstmt.executeQuery();

업데이트 내가 대신 다른 MySQL 데이터베이스 (아마 다른 버전 또는 무언가)에 대한 널 (null)입니다 ""= 사용했다 네

해결법

  1. ==============================

    1.'0'(단지 예를 들어)와 같은 (I가 된 PreparedStatement를 사용하여 할 수있는 다른 방법을 알고하지 않기 때문에) 나는 당신이 당신의 NULL 선택된 값에 대한 기본 값이 있다고 가정합니다.

    '0'(단지 예를 들어)와 같은 (I가 된 PreparedStatement를 사용하여 할 수있는 다른 방법을 알고하지 않기 때문에) 나는 당신이 당신의 NULL 선택된 값에 대한 기본 값이 있다고 가정합니다.

    이 알고, 내가 SQL의이 종류를 사용하는 경향이 :

    SELECT *
    FROM Courses
    WHERE
        (product = ? or ? = '0')
        and (location = ?  or ? = '0')
        and (courseType = ? or ? = '0')
        and (category = ? or ? = '0')
    

    이 방법을 사용하면 IF 사용을 활용하여 데이터베이스 작업을 처리 할 수 ​​있습니다. 이에 대한 유일한 나쁜 점은 (아무것도 =이 생에서 무료입니다 \)를 두 번 모든 변수를 설정해야한다는 것입니다.

    편집 : 나는 귀하의 요구 사항에 따라 검사를했습니다. 먼저 SQL 테이블과 내용 :

    create table pruebaMultiSelect
    (id int primary key auto_increment,
    nombre varchar(50),
    tipo varchar(10),
    categoria varchar(10));
    
    insert into pruebaMultiSelect values
    (null, 'Luiggi', 'A', 'X');
    
    insert into pruebaMultiSelect values
    (null, 'Thomas', 'A', 'Y');
    
    insert into pruebaMultiSelect values
    (null, 'Jose', 'B', 'X');
    
    insert into pruebaMultiSelect values
    (null, 'Trina', 'B', 'Y');
    

    이제, 관련 자바 코드 :

    public class DBTest {
    
        public void testPreparedStatement(String p1, String p2) throws SQLException {
            Connection con = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
            try {
                con = getConnection();
                pstmt = con.prepareStatement("SELECT * FROM pruebaMultiSelect WHERE (tipo = ? OR ? = 'EMPTY') "
                        + "AND (categoria = ? OR ? = 'EMPTY')");
                pstmt.setString(1, p1);
                pstmt.setString(2, p1);
                pstmt.setString(3, p2);
                pstmt.setString(4, p2);
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    System.out.printf("%5d %15s\n", rs.getInt(1), rs.getString(2));
                }
            } catch(ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                rs.close();
                pstmt.close();
                con.close();
            }
        }
    
        public Connection getConnection() throws SQLException, ClassNotFoundException {
            Class.forName("com.mysql.jdbc.Driver");
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/luiggi_test", "user", "password");
        }
    
        public static void main(String[] args) throws SQLException {
            //this will return all the data
            String p1 = "EMPTY";
            String p2 = "EMPTY";
            new DBTest().testPreparedStatement(p1, p2);
        }
    }
    

    MySQL은 5.1.18을 사용하여 테스트.

  2. ==============================

    2.이 같은 헬퍼 메소드와 동적 쿼리를 작성하는 경향이있다 :

    이 같은 헬퍼 메소드와 동적 쿼리를 작성하는 경향이있다 :

    StringBuilder query = new StringBuidler();
    query.append("SELECT foo, bar FROM baz");
    query.append(buildProductClause(product));
    query.append(buildLocationClause(location));
    query.append(buildCourseTypeClause(courseType));
    // etc...
    

    당신은 여전히 ​​준비된 문을 사용하려는 경우 인수의 배열을 구축하는 멤버 필드를 사용할 수 있습니다.

  3. from https://stackoverflow.com/questions/15121869/sql-prepared-statement-how-to-select-via-multiple-possible-menu-selections by cc-by-sa and MIT license