"select from"을 사용하지 않고 테이블이 존재하는지 확인


176

테이블 에서 값을 선택하고 확인 하지 않고 테이블이 존재하는지 확인하는 방법 이 있습니까?

즉, SELECT testcol FROM testtable돌아가서 반환되는 필드 수를 확인할 수는 있지만 더 직접적이고 우아한 방법이 있어야합니다.


답변을 보려면 stackoverflow.com/a/167680/12495091 을 방문하십시오 !!!!!!!!!
Saurabh Chopra

@SaurabhChopra 그것은 SQL Server를위한 것입니다. 이것은 MySql에 관한 것입니다.
Alejandro

답변:


323

정확하려면 INFORMATION_SCHEMA를 사용하십시오 .

SELECT * 
FROM information_schema.tables
WHERE table_schema = 'yourdb' 
    AND table_name = 'testtable'
LIMIT 1;

또는 사용할 수 있습니다 SHOW TABLES

SHOW TABLES LIKE 'yourtable';

결과 집합에 행이 있으면 테이블이 존재합니다.


3
그래, 그것은 잘 작동하고 우아하지만 여전히 SELECT...FROM구문을 사용 합니다 ... 나는 일종의 것을 찾고있었습니다EXISTS testtable
Ben

9
Marc와 나 자신이 그렇게 말한 방법은 올바른 방법입니다. '존재'형식 문 MySql이 없습니다. MySql의 'Exists'는 SELECT, UPDATE 또는 DELETE와 같은 연산이 필요한 절입니다.
doogle

@Steve 세 번째 옵션은 이식성이 없습니다.
ta.speot.is는

1
@SergioTulentsev 태그에 관계없이 독점적 인 방법보다 휴대용 방법을 선호합니다.
ta.speot.is은 (는)

1
@Filype 쿼리가 성공했는지 여부 만 확인하기 때문에 이것은 실제로 문제가되지 않습니다. 테이블에 행이없는 경우 빈 결과 집합만으로도 쿼리가 계속 성공합니다.
Bill Dami

66
SELECT count(*)
FROM information_schema.TABLES
WHERE (TABLE_SCHEMA = 'your_db_name') AND (TABLE_NAME = 'name_of_table')

0이 아닌 수를 얻으면 테이블이 존재합니다.


2
나는 여기서 일어난 일을 정말로 얻지 못한다. 나는 지금하고 있기 때문에 답변을 확인했으며 Sergio Tulentsevs의 답변이 더 일찍 (1 분) 3 가지 해결책을 제공했지만 사실이 가장 효과적입니다. 왜 내가 더 원하는 것을 선택해야합니까? 이 경우 "부울"1/0이 필요합니다. 테이블이 존재합니까? 나는 모든 것을 제한하고 싶지 않으며, 아무것도 좋아하지 않고, 오류를 원하지 않습니다. 이것이 정답입니다.
vaso123

1
A의 것을 참고 TEMPORARY TABLE이 작동하지 않습니다.
Thomas Lobker '10

27

성능 비교 :

  • 약 11,000 개의 테이블이있는 DB의 MySQL 5.0.77
  • 캐시되지 않도록 최근에 사용하지 않은 테이블을 선택합니다.
  • 시도당 평균 10 회 이상 (참고 : 캐싱을 피하기 위해 다른 테이블로 수행됨).

322ms : show tables like 'table201608';

691ms : select 1 from table201608 limit 1;

319ms : SELECT count(*) FROM information_schema.TABLES WHERE (TABLE_SCHEMA = 'mydb') AND (TABLE_NAME = 'table201608');

단기간에 많은 HTML 요청과 같이이 작업을 많이 수행하면 평균 200ms 이상으로 캐시되므로 두 번째는 훨씬 빠릅니다.


16

INFORMATION_SCHEMA tables시스템 뷰를 쿼리 할 수 ​​있습니다 .

SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'databasename'
AND table_name = 'testtable';

행이 반환되지 않으면 테이블이 존재하지 않는 것입니다.


9

위의 내용을 모두 읽은 후 다음 진술을 선호합니다.

SELECT EXISTS(
       SELECT * FROM information_schema.tables 
       WHERE table_schema = 'db' 
       AND table_name = 'table'
);

그것은 당신이하고 싶은 것을 정확하게 나타내고 실제로 '부울'을 반환합니다.


2
이것은 받아 들여야 할 대답입니다. 간결하고 간단한
Dika

부울을 반환하지 않고 결과 집합을 반환합니다. var_dump :mysqli_result Object ( [current_field] => 0 [field_count] => 1 [lengths] => [num_rows] => 1 [type] => 0 )
camslice

7

오류에 의존하는 대신 INFORMATION_SCHEMA.TABLES테이블이 존재하는지 쿼리 할 수 있습니다. 레코드가 있으면 존재합니다. 레코드가 없으면 존재하지 않습니다.


1
아, 이제 점점 가까워지고 있습니다! 시도해 볼게요

1
@Steve : 여전히 그렇습니다 SELECT FROM. :-)
Sergio Tulentsev

7

다음은 SELECT * FROM이 아닌 테이블입니다.

SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = not exist

데이터베이스 전문가로부터 이것을 얻었습니다. 내가 들었던 것은 다음과 같습니다.

select 1 from `tablename`; //avoids a function call
select * from IMFORMATION_SCHEMA.tables where schema = 'db' and table = 'table' // slow. Field names not accurate
SHOW TABLES FROM `db` LIKE 'tablename'; //zero rows = not exist

가장 쉽고 효율적입니다.
e2-e4

3

위에서 수정 한이 솔루션에는 현재 데이터베이스에 대한 명시적인 지식이 필요하지 않습니다. 그런 다음 더 유연합니다.

SELECT count(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'yourtable' 
AND TABLE_SCHEMA in (SELECT DATABASE());

2

추가 방법을 추가하기 위해 필요한 방법에 따라 er_no_such_table error : 1146에 대한 핸들러 를 다음과 같이 사용할 수 있습니다 .

DELIMITER ;;
CREATE PROCEDURE `insert_in_my_table`(in my_var INT)
BEGIN
   -- Error number for table not found
   DECLARE CONTINUE HANDLER FOR 1146
   BEGIN
      -- table doesn't exists, do something...
      CREATE TABLE my_table(n INT);
      INSERT INTO my_table (n) values(my_var);
   END;
      -- table does exists, do something...
      INSERT INTO my_table (n) values(my_var);
END ;;
DELIMITER ;

2

'table_name'과 같은 테이블 표시

이것이 행> 0을 반환하면 테이블이 존재합니다.


1

아래와 같이 할 수 있습니다 :

            string strCheck = "SHOW TABLES LIKE \'tableName\'";
            cmd = new MySqlCommand(strCheck, connection);
            if (connection.State == ConnectionState.Closed)
            {
                connection.Open();
            }
            cmd.Prepare();
            var reader = cmd.ExecuteReader();
            if (reader.HasRows)
            {                             
              Console.WriteLine("Table Exist!");
            }
            else
            {                             
              Console.WriteLine("Table does not Exist!");
            }

1

답변을 확장하면 테이블이 존재하는지 여부에 따라 TRUE / FALSE를 반환하는 함수를 추가로 작성할 수 있습니다.

CREATE FUNCTION fn_table_exists(dbName VARCHAR(255), tableName VARCHAR(255))
  RETURNS BOOLEAN
  BEGIN
    DECLARE totalTablesCount INT DEFAULT (
      SELECT COUNT(*)
      FROM information_schema.TABLES
      WHERE (TABLE_SCHEMA COLLATE utf8_general_ci = dbName COLLATE utf8_general_ci)
        AND (TABLE_NAME COLLATE utf8_general_ci = tableName COLLATE utf8_general_ci)
    );
    RETURN IF(
      totalTablesCount > 0,
      TRUE,
      FALSE
    );
END
;


SELECT fn_table_exists('development', 'user');

1

이 컴팩트 메소드는 존재하는 경우 1을 리턴하고 존재하지 않는 경우 0을 리턴합니다.

set @ret = 0; 
SELECT 1 INTO @ret FROM information_schema.TABLES 
         WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'my_table'; 
SELECT @ret;

mysql 함수에 넣을 수 있습니다

DELIMITER $$
CREATE FUNCTION ExistTable (_tableName varchar(255))
RETURNS tinyint(4)
SQL SECURITY INVOKER
BEGIN
  DECLARE _ret tinyint;
  SET _ret = 0;
  SELECT
    1 INTO _ret
  FROM information_schema.TABLES
  WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = _tablename LIMIT 1;
  RETURN _ret;
END
$$
DELIMITER ;

전화 해

Select ExistTable('my_table');

존재하는 경우 1을 리턴하고 존재하지 않는 경우 0을 리턴하십시오.


0

나는 이것을 PHP에서 사용한다.

private static function ifTableExists(string $database, string $table): bool
    {
        $query = DB::select("
            SELECT 
                IF( EXISTS 
                    (SELECT * FROM information_schema.COLUMNS
                        WHERE TABLE_SCHEMA = '$database'
                        AND TABLE_NAME = '$table'
                        LIMIT 1),
                1, 0)
                AS if_exists
        ");

        return $query[0]->if_exists == 1;
    }

0

여기에 대한 답변과 관련하여 몇 가지 문제가 있습니다.

1) INFORMATION_SCHEMA.TABLES하지 않습니다 TEMPORARY 테이블을 포함 .

2) 모든 유형의 SHOW쿼리 사용SHOW TABLES LIKE 'test_table' 하면 결과 집합을 클라이언트에 강제로 반환합니다. 결과 집합을 반환하는 저장 프로 시저 내에서 테이블이 서버 측에 있는지 확인하는 바람직하지 않은 동작입니다.

3) 일부 사용자가 언급했듯이 사용 방법에주의해야합니다. SELECT 1 FROM test_table LIMIT 1 .

당신이 같은 것을하면 :

SET @table_exists = 0;
SET @table_exists = (SELECT 1 FROM test_table LIMIT 1);

테이블에 행이 없으면 예상 결과를 얻지 못합니다.

아래는 모든 테이블에서 작동하는 저장 프로 시저입니다 (심지어 TEMPORARY).

다음과 같이 사용할 수 있습니다.

SET @test_table = 'test_table';
SET @test_db = NULL;
SET @does_table_exist = NULL;

CALL DoesTableExist(@test_table, @test_db, @does_table_exist);

SELECT @does_table_exist;

코드:

/*
    p_table_name is required
    p_database_name is optional
        if NULL is given for p_database_name, then it defaults to the currently selected database
    p_does_table_exist
        The @variable to save the result to

    This procedure attempts to
        SELECT NULL FROM `p_database_name`.`p_table_name` LIMIT 0;

    If [SQLSTATE '42S02'] is raised, then
        SET p_does_table_exist = 0
    Else
        SET p_does_table_exist = 1

    Info on SQLSTATE '42S02' at:
        https://dev.mysql.com/doc/refman/5.7/en/server-error-reference.html#error_er_no_such_table
*/

DELIMITER $$

DROP PROCEDURE IF EXISTS DoesTableExist
$$

CREATE PROCEDURE         DoesTableExist (
    IN p_table_name VARCHAR(64),
    IN p_database_name VARCHAR(64),
    OUT p_does_table_exist TINYINT(1) UNSIGNED
)
BEGIN
    /* 793441 is used in this procedure for ensuring that user variables have unique names */

    DECLARE EXIT HANDLER FOR SQLSTATE '42S02'
    BEGIN
        SET p_does_table_exist = 0
        ;
    END
    ;


    IF p_table_name IS NULL THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'DoesTableExist received NULL for p_table_name.';
    END IF;


    /* redirect resultset to a dummy variable */

    SET @test_select_sql_793441 = CONCAT(
        "SET @dummy_var_793441 = ("
            " SELECT"
                " NULL"
            " FROM ",
                IF(
                    p_database_name IS NULL,
                    "",
                    CONCAT(
                        "`",
                        REPLACE(p_database_name, "`", "``"),
                        "`."
                    )
                ),
                "`",
                REPLACE(p_table_name, "`", "``"),
                "`"
            " LIMIT 0"
        ")"
    )
    ;

    PREPARE _sql_statement FROM @test_select_sql_793441
    ;
    SET @test_select_sql_793441 = NULL
    ;
    EXECUTE _sql_statement
    ;
    DEALLOCATE PREPARE _sql_statement
    ;

    SET p_does_table_exist = 1
    ;
END
$$

DELIMITER ;

0

이것은 임시 테이블과 일반 테이블을 모두 확인하는 '이동'EXISTS 절차였습니다. 이 절차는 MySQL 버전 5.6 이상에서 작동합니다. @DEBUG 매개 변수는 선택 사항입니다. 기본 스키마가 가정되지만 @s 문의 테이블에 연결할 수 있습니다.

drop procedure if exists `prcDoesTableExist`;
delimiter #
CREATE PROCEDURE `prcDoesTableExist`(IN pin_Table varchar(100), OUT pout_TableExists BOOL)
BEGIN
    DECLARE `boolTableExists` TINYINT(1) DEFAULT 1;
    DECLARE CONTINUE HANDLER FOR 1243, SQLSTATE VALUE '42S02' SET `boolTableExists` := 0;
        SET @s = concat('SELECT null FROM `', pin_Table, '` LIMIT 0 INTO @resultNm');
    PREPARE stmt1 FROM @s;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;
    set pout_TableExists = `boolTableExists`; -- Set output variable
    IF @DEBUG then
        select IF(`boolTableExists`
            , CONCAT('TABLE `', pin_Table, '` exists: ', pout_TableExists)
            , CONCAT('TABLE `', pin_Table, '` does not exist: ', pout_TableExists)
        ) as result;
    END IF;
END #
delimiter ;

다음은 @debug를 사용한 호출 문 예제입니다.

set @DEBUG = true;
call prcDoesTableExist('tempTable', @tblExists);
select @tblExists as '@tblExists';

@tblExists 변수는 부울을 반환합니다.


-1

SELECT를 제외한 모든 옵션은 SELECT에 사용 된 데이터베이스 이름을 허용하지 않으므로 다음과 같이 작성했습니다.

SELECT COUNT(*) AS cnt FROM information_schema.TABLES 
WHERE CONCAT(table_schema,".",table_name)="db_name.table_name";
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.