복붙노트

[SQL] 무엇 SQL 데이터베이스는 CHECK 제약 조건에 서브 쿼리를 지원합니까?

SQL

무엇 SQL 데이터베이스는 CHECK 제약 조건에 서브 쿼리를 지원합니까?

CHECK 제약 조건에서 어떤 SQL 데이터베이스 (있는 경우), 지원 서브 쿼리?

현재와 ​​내가 아는 한, 오라클, MySQL은, 및 PostgreSQL은하지 않습니다.

편집하다

(해설 초기 응답에 따라.) 나는 이런 식으로 뭔가를 찾고 있어요 :

CREATE TABLE personnel (
  ...,
department VARCHAR(64) NOT NULL,
salary NUMERIC NOT NULL,
CHECK (salary >= (SELECT MIN(p.salary) FROM payranges p WHERE p.dept = department)
        AND
       salary <= (SELECT MAX(p.salary) FROM payranges p WHERE p.dept = department)
)

최신 정보

MS 액세스와 파이어 버드는 모두이 기능을 지원합니다.

해결법

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

    1.이 엔트리 레벨 표준 SQL-92 및 액세스 CHECK 제약이 거의 단말과 액세스 팀의 설명서를 지원하지 않기 때문에 내가 주저 Access 데이터베이스 엔진 (ACE, 제트, 무엇이든) CHECK 제약에서 지원하는 하위 쿼리하지만은 SQL DBMS를 호출 .

    이 엔트리 레벨 표준 SQL-92 및 액세스 CHECK 제약이 거의 단말과 액세스 팀의 설명서를 지원하지 않기 때문에 내가 주저 Access 데이터베이스 엔진 (ACE, 제트, 무엇이든) CHECK 제약에서 지원하는 하위 쿼리하지만은 SQL DBMS를 호출 .

    어떤 문서에이 없기 때문에 예를 들어, 나는 액세스 CHECK 제약 (그들은 각 SQL 문 다음에 확인해야한다는 SQL-92 지정)에 영향을받는 각 행에 대해 선택되어 있는지하지만이 버그 우리가 모르는 기능입니다 여부를 입증 할 수 인용하다.

    여기에 하위 쿼리를 포함하는 CHECK 제약 조건의 매우 간단한 예입니다. 그것은 전체 SQL-92 준수 및 액세스에서 잘 작동합니다. 아이디어는 두 행의 최대 테이블을 제한하는 것입니다 (다음 SQL DDL은 ANSI-92 쿼리 모드 예는 Access.CurrentProject.Connection 같은 ADO 연결을 사용 필요) :

    CREATE TABLE T1 
    (
     c INTEGER NOT NULL UNIQUE
    );
    
    ALTER TABLE T1 ADD
       CONSTRAINT max_two_rows
          CHECK (
                 NOT EXISTS (
                             SELECT 1
                               FROM T1 AS T
                             HAVING COUNT(*) > 2
                            )
                );
    

    그러나 여기에 SQL-92입니다 또 다른 예는, Access에서 만들 수 있습니다 (일부 유효한 검사를 다시 시작해야 :( 내 컴퓨터 필요하지만 제대로 작동하지 않는 무시 무시한 사고와 접근에 실패합니다. 생각 만하는 것입니다 테이블에 정확히 두 개의 행 수 (또는 제로 행 : 제약 빈 테이블 테스트되지 않음) :

    CREATE TABLE T2 
    ( 
     c INTEGER NOT NULL UNIQUE 
    );
    
    ALTER TABLE T2 ADD 
       CONSTRAINT exactly_two_rows 
          CHECK ( 
                 NOT EXISTS ( 
                             SELECT 1 
                               FROM T2 AS T 
                             HAVING COUNT(*) <> 2 
                            ) 
                );
    

    예를 들어, 같은 문에 두 행을 삽입하려고 (가정 테이블 T1은 적어도 하나 개의 행을 갖는다) :

    SELECT DT1.c
      FROM (
            SELECT DISTINCT 1 AS c
              FROM T1
            UNION ALL
            SELECT DISTINCT 2
              FROM T1
           ) AS DT1;
    

    그러나,이 물린의 체크가됩니다. 이 (또한 시험) 각 행은 구속이 SQL 문장 레벨에서 시험되는 SQL-92를 지정하는 반면, 테이블에 추가 된 후 검사 시험을 의미한다.

    그것은 예를 들면 '(너무 많은 당신이 Access2010 때까지 그렇지 않으면 실제 키가 없을 것입니다 어떤 트리거 기능과 특정 자주 사용되는 테이블을 가지고 있지 않은 것을 고려할 때 액세스가 진정 테이블 수준 CHECK 제약 조건을 가지고 놀랄로 오지한다 유효한 상태 임시 테이블 시퀀스 '키). Access2010 트리거들이 오히려 문 수준에서보다, 행 레벨에서 테스트하는 것과 같은 버그 / 기능을 고통을합니다.

    다음은 VBA 상술 한 두 시나리오를 재현하는 것이다. 어떤 VBA / VB6 표준 .BAS 모듈에 복사하여 붙여 넣기 (예를 들어 Excel을 사용), 더 참조 할 필요가 없습니다. 당신의 임시 폴더에 새 .MDB를 작성 테이블, 데이터 및 제약 / 작동 작업을하지 않는 테스트 생성 (힌트 : 중단 점 설정, 코드를 단계별, 주석을 읽기) :

    Sub AccessCheckSubqueryButProblem()
    
      On Error Resume Next
      Kill Environ$("temp") & "\DropMe.mdb"
      On Error GoTo 0
    
      Dim cat
      Set cat = CreateObject("ADOX.Catalog")
      With cat
        .Create _
            "Provider=Microsoft.Jet.OLEDB.4.0;" & _
            "Data Source=" & _
            Environ$("temp") & "\DropMe.mdb"
        With .ActiveConnection
    
          Dim Sql As String
    
          Sql = _
          "CREATE TABLE T1 " & vbCr & _
          "( " & vbCr & _
          " c INTEGER NOT NULL UNIQUE " & vbCr & _
          ");"
          .Execute Sql
    
          Sql = _
          "ALTER TABLE T1 ADD " & vbCr & _
          "   CONSTRAINT max_two_rows " & vbCr & _
          "      CHECK ( " & vbCr & _
          "             NOT EXISTS ( " & vbCr & _
          "                         SELECT 1 " & vbCr & _
          "                           FROM T1 AS T " & vbCr & _
          "                         HAVING COUNT(*) > 2 " & vbCr & _
          "                        ) " & vbCr & _
          "            );"
          .Execute Sql
    
          Sql = _
          "INSERT INTO T1 (c) VALUES (1);"
          .Execute Sql
    
          Sql = _
          "INSERT INTO T1 (c) VALUES (2);"
          .Execute Sql
    
          ' The third row should (and does)
          ' cause the CHECK to bite
          On Error Resume Next
          Sql = _
          "INSERT INTO T1 (c) VALUES (3);"
          .Execute Sql
          MsgBox Err.Description
          On Error GoTo 0
    
          Sql = _
          "CREATE TABLE T2 " & vbCr & _
          "( " & vbCr & _
          " c INTEGER NOT NULL UNIQUE " & vbCr & _
          ");"
          .Execute Sql
    
          Sql = _
          "ALTER TABLE T2 ADD " & vbCr & _
          "   CONSTRAINT exactly_two_rows " & vbCr & _
          "      CHECK ( " & vbCr & _
          "             NOT EXISTS ( " & vbCr & _
          "                         SELECT 1 " & vbCr & _
          "                           FROM T2 AS T " & vbCr & _
          "                         HAVING COUNT(*) <> 2 " & vbCr & _
          "                        ) " & vbCr & _
          "            );"
          .Execute Sql
    
          ' INSERTing two rows in the same SQL statement
          ' should succeed according to SQL-92
          ' but fails (and we have no docs from MS
          ' to indicate whether this is a bug/feature)
          On Error Resume Next
          Sql = _
          "INSERT INTO T2 " & vbCr & _
          "   SELECT c " & vbCr & _
          "     FROM T1;"
          .Execute Sql
          MsgBox Err.Description
          On Error GoTo 0
    
    
        End With
        Set .ActiveConnection = Nothing
      End With
    End Sub
    
  2. ==============================

    2.파이어 버드 문서는 CHECK 제약 조건에 하위 쿼리를 허용했다.

    파이어 버드 문서는 CHECK 제약 조건에 하위 쿼리를 허용했다.

  3. ==============================

    3.SQL 서버 2000 + 쿼리를 포함 UDF를 할 수 있습니다 : 당신이 직접 하위 쿼리를 사용할 수 없습니다

    SQL 서버 2000 + 쿼리를 포함 UDF를 할 수 있습니다 : 당신이 직접 하위 쿼리를 사용할 수 없습니다

    그러나, 그들은 높은 부하에서 동시 없습니다

  4. ==============================

    4.H2는 제약 조건에 하위 쿼리를 지원합니다. 더 적은 PSQL 모드 : P

    H2는 제약 조건에 하위 쿼리를 지원합니다. 더 적은 PSQL 모드 : P

    MariaDB는 제약 조건으로 지원하는 것 같습니다하지 않습니다.

    ALTER TABLE Table_1 ADD CONSTRAINT constraint_1 
    CHECK (column_1 > (SELECT MAX(column_2) FROM Table_2) NOT DEFERRABLE;
    

    참고로,이 MariaDB에 점검 제한 조건을 구현하기위한 티켓입니다. 2015년 7월 23일의, 그것은 "열기"상태에 아직도있다.

  5. ==============================

    5.확신 TRIGGER는 당신이 언급 한 각 데이터베이스에서 작동하고 당신은 당신의 제약 조건 해결에 더 많은 "팔꿈치 방을"얻을.

    확신 TRIGGER는 당신이 언급 한 각 데이터베이스에서 작동하고 당신은 당신의 제약 조건 해결에 더 많은 "팔꿈치 방을"얻을.

  6. ==============================

    6.SQL 서버는 지원 다음 링크에서 유용한 정보를 찾을 수 있습니다

    SQL 서버는 지원 다음 링크에서 유용한 정보를 찾을 수 있습니다

    http://www.craigsmullins.com/sql_1298.htm

    그들은 POSTGRESQL도 지원하는 말

    http://developer.postgresql.org/pgdocs/postgres/ddl-constraints.html

    DB2는 CHECK 제약 조건을 지원합니다

    http://www.ibm.com/developerworks/data/library/techarticle/dm-0401melnyk/

  7. from https://stackoverflow.com/questions/6195881/what-sql-databases-support-subqueries-in-check-constraints by cc-by-sa and MIT license