복붙노트

[SQL] SQL 테이블이 존재하는지 확인

SQL

SQL 테이블이 존재하는지 확인

테이블이 데이터베이스 독립적 인 방식으로 SQL 데이터베이스에 존재하는지 확인하는 가장 좋은 방법은 무엇입니까?

나는 함께했다 :

   bool exists;
   const string sqlStatement = @"SELECT COUNT(*) FROM my_table";

   try
    {
       using (OdbcCommand cmd = new OdbcCommand(sqlStatement, myOdbcConnection))
       {
            cmd.ExecuteScalar();
            exists = true;
       }
    }
    catch
    {
        exists = false;
    }

이 작업을 수행하는 더 좋은 방법이 있나요? 데이터베이스에 대한 연결이 실패 할 경우이 방법은 작동하지 않습니다. 나는 사이베이스, SQL 서버, 오라클에 대한 방법 그러나 아무것도 발견 한 모든 데이터베이스에 대해 작동합니다.

해결법

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

    1.

    bool exists;
    
    try
    {
        // ANSI SQL way.  Works in PostgreSQL, MSSQL, MySQL.  
        var cmd = new OdbcCommand(
          "select case when exists((select * from information_schema.tables where table_name = '" + tableName + "')) then 1 else 0 end");
    
        exists = (int)cmd.ExecuteScalar() == 1;
    }
    catch
    {
        try
        {
            // Other RDBMS.  Graceful degradation
            exists = true;
            var cmdOthers = new OdbcCommand("select 1 from " + tableName + " where 1 = 0");
            cmdOthers.ExecuteNonQuery();
        }
        catch
        {
            exists = false;
        }
    }
    
  2. ==============================

    2.나는 이것이 매우 구체적인 무언가를하기 때문에 모든 데이터베이스에 대한 작품의 DB가 구축 방법에 의존 한 일반적인 방법이 존재 함을 생각하지 않습니다.

    나는 이것이 매우 구체적인 무언가를하기 때문에 모든 데이터베이스에 대한 작품의 DB가 구축 방법에 의존 한 일반적인 방법이 존재 함을 생각하지 않습니다.

    하지만, 왜 특정 쿼리를 사용하여이 작업을 수행 할 수 있습니까? 당신은 멀리 당신이 원하는 것과 구현 추상 수없는 이유는 무엇입니까? 내 말은 : 다른 사람들이 일반적인 인터페이스, 예를 들어 'TableExists (문자열 TABLENAME)'라는 방법을 만들 수 없습니다 이유. 그런 다음, 당신이 지원하고자하는 각 DBMS를 들어, 클래스 구현이 인터페이스를 작성하고 TableExists 방법, 당신은이 DBMS에 대한 특정 로직을 작성. 의 SQLServer 구현은 다음을 sysobjects을 조회하는 쿼리가 포함됩니다.

    응용 프로그램에서는 주어진 상황에 대한 올바른 구현을 생성하는 팩토리 클래스를 가질 수 있습니다, 그리고 당신은 단지 TableExists 메서드를 호출합니다.

    예를 들어 :

    IMyInterface foo = MyFactory.CreateMyInterface (SupportedDbms.SqlServer);
    
    if( foo.TableExists ("mytable") )
    ...
    

    나는 이것이 내가 할 방법을 생각합니다.

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

    3.당신이 데이터베이스 독립하려는 경우 당신은 최소한의 기준을 가정해야합니다. 당신처럼 대해 쿼리 수 있도록 IIRC은 ANSI INFORMATION_SCHEMA 뷰는, ODBC 적합성 필요합니다 :

    당신이 데이터베이스 독립하려는 경우 당신은 최소한의 기준을 가정해야합니다. 당신처럼 대해 쿼리 수 있도록 IIRC은 ANSI INFORMATION_SCHEMA 뷰는, ODBC 적합성 필요합니다 :

    select count (*) 
      from information_schema.tables 
     where table_name = 'foobar'
    

    ODBC를 사용하고 있음을 감안할 때, 당신은 또한뿐만 아니라이 메타 데이터를 검색하기 위해 다양한 ODBC API 호출을 사용할 수 있습니다.

    곰 염두에에 이식 동일시 회 기록 당신은 아직도 당신이 지원하고자하는 모든 플랫폼에서 응용 프로그램을 테스트해야 할 것되도록 테스트 어디서나. 당신은 단지 테스트를 위해 너무 많은 자원을 가지고 당신이 본질적으로 가능한 데이터베이스 플랫폼의 한정된 수에 제한됩니다이 의미합니다.

    결론적으로 당신이 (꽤 많이 힘들어은 SQL을 찾습니다보다 인) 응용 프로그램에 대한 가장 낮은 공통 분모를 찾거나 비 휴대용 함수 당 플랫폼에 연결 할 수있는 플랫폼에 의존하는 섹션을 구축 할 필요가있다 기초.

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

    4.나는 완전히 프레데릭 Gheysels 대답을 지원합니다. 여러 데이터베이스 시스템을 지원해야하는 경우 데이터베이스 시스템 당 특정 구현과 추상 인터페이스에 대해 코드를 구현해야합니다. 단지 기존 테이블 검사에 비해 호환되지 않는 구문 (예를 들면 : 행의 특정 번호로 쿼리를 제한)의 더 많은 사례가있다.

    나는 완전히 프레데릭 Gheysels 대답을 지원합니다. 여러 데이터베이스 시스템을 지원해야하는 경우 데이터베이스 시스템 당 특정 구현과 추상 인터페이스에 대해 코드를 구현해야합니다. 단지 기존 테이블 검사에 비해 호환되지 않는 구문 (예를 들면 : 행의 특정 번호로 쿼리를 제한)의 더 많은 사례가있다.

    당신이 정말로 당신의 예에서 예외 처리를 사용하여 검사를 수행해야하는 경우, 당신은 데이터베이스가 할 수있는 실제 선택 작업이 없기 때문에 COUNT (*)보다 효율적입니다 다음 쿼리를 사용한다 :

    SELECT 1 FROM my_table WHERE 1=2
    
  5. ==============================

    5.DBMS에 실제로 큰 테이블에 대한 약간의 시간이 걸릴 수있는 가서 그것을 할 것 같은 나는 XXXXXX에서 SELECT COUNT (X)를 실행하지 않도록한다.

    DBMS에 실제로 큰 테이블에 대한 약간의 시간이 걸릴 수있는 가서 그것을 할 것 같은 나는 XXXXXX에서 SELECT COUNT (X)를 실행하지 않도록한다.

    대신 mysterytable 쿼리에서 선택 *을 준비합니다. 는 mysterytable이 존재하지 않는 경우 실패합니다 준비합니다. 실제로 준비된 문을 수행 할 필요가 없습니다.

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

    6.내 직업에 현재 프로젝트에서 나는 데이터베이스 유형을 많이 지원하는 것이다 쓰기의 데이터 에이전트 '로해야합니다.

    내 직업에 현재 프로젝트에서 나는 데이터베이스 유형을 많이 지원하는 것이다 쓰기의 데이터 에이전트 '로해야합니다.

    내가 다음에하기로 결정 그래서 : 서브 클래스의 모든 데이터베이스 특정 순간에 가상 메소드와 재정의를 사용하여 기본 (데이터베이스 독립) 기능을 기본 클래스를 작성

  7. ==============================

    7.다음은 나를 위해 잘 작동합니다 ...

    다음은 나를 위해 잘 작동합니다 ...

    private bool TableExists(SqlConnection conn, string database, string name)
    {
        string strCmd = null;
        SqlCommand sqlCmd = null;
    
        try
        {
            strCmd = "select case when exists((select '['+SCHEMA_NAME(schema_id)+'].['+name+']' As name FROM [" + database + "].sys.tables WHERE name = '" + name + "')) then 1 else 0 end";
            sqlCmd = new SqlCommand(strCmd, conn);
    
            return (int)sqlCmd.ExecuteScalar() == 1;
        }
        catch { return false; }
    }
    
  8. ==============================

    8.당신이 시도 - 캐치 솔루션을 피하고 싶은 경우에, 나는 sys.tables를 사용하여,이 방법을 제안하고 있습니다

    당신이 시도 - 캐치 솔루션을 피하고 싶은 경우에, 나는 sys.tables를 사용하여,이 방법을 제안하고 있습니다

    private bool IsTableExisting(string table)
        {
            string command = $"select * from sys.tables";
            using (SqlConnection con = new SqlConnection(Constr))
            using (SqlCommand com = new SqlCommand(command, con))
            {
                SqlDataReader reader = com.ExecuteReader();
                while (reader.Read())
                {
                    if (reader.GetString(0).ToLower() == table.ToLower())
                        return true;
                }
                reader.Close();
            }
            return false;
        }
    
  9. ==============================

    9.아주 간단한

    아주 간단한

    use YOUR_DATABASE --OPTIONAL
    SELECT count(*) as Exist from INFORMATION_SCHEMA.TABLES where table_name = 'YOUR_TABLE_NAME'
    

    답이 1 인 경우, 테이블이있다. 대답은 0의 경우, 테이블이 없습니다.

  10. from https://stackoverflow.com/questions/464474/check-if-a-sql-table-exists by cc-by-sa and MIT license