해당 열이있는 경우 ALTER를 사용하여 MySQL 테이블의 열을 삭제하는 방법은 무엇입니까?
나는 사용할 수 있다는 것을 알고 ALTER TABLE my_table DROP COLUMN my_column
있지만 my_column
존재하지 않으면 오류가 발생 합니다. 조건부로 열을 삭제하는 대체 구문이 있습니까?
MySQL 버전 4.0.18을 사용하고 있습니다.
답변
MySQL의 경우 MySQL 기능 요청 이 없습니다 .
어쨌든 이것을 허용하는 것은 정말 나쁜 생각입니다. IF EXISTS
알 수없는 구조를 가진 데이터베이스에서 파괴적인 작업을 실행하고 있음을 나타냅니다. 빠르고 더러운 로컬 작업에 이것이 허용되는 상황이있을 수 있지만 프로덕션 데이터 (이전 등)에 대해 그러한 명령문을 실행하려는 유혹이 있다면 불장난입니다.
그러나 주장한다면 클라이언트에서 먼저 존재를 확인하거나 오류를 포착하는 것은 어렵지 않습니다.
MariaDB는 10.0.2부터 다음을 지원합니다.
DROP [COLUMN] [IF EXISTS] col_name
즉
ALTER TABLE my_table DROP IF EXISTS my_column;
그러나 MySQL의 여러 포크 중 하나만 지원하는 비표준 기능에 의존하는 것은 틀림없이 나쁜 생각입니다.
답변
MySQL에서는 이에 대한 언어 수준 지원이 없습니다. 다음은 5.0+의 MySQL information_schema 메타 데이터와 관련된 해결 방법이지만 4.0.18에서는 문제를 해결하지 않습니다.
drop procedure if exists schema_change;
delimiter ';;'
create procedure schema_change() begin
/* delete columns if they exist */
if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column1') then
alter table table1 drop column `column1`;
end if;
if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column2') then
alter table table1 drop column `column2`;
end if;
/* add columns */
alter table table1 add column `column1` varchar(255) NULL;
alter table table1 add column `column2` varchar(255) NULL;
end;;
delimiter ';'
call schema_change();
drop procedure if exists schema_change;
나는 블로그 포스트 에 좀 더 자세한 정보를 썼다 .
답변
이것이 오래된 스레드라는 것을 알고 있지만 저장 프로 시저를 사용하지 않고이 요구 사항을 처리하는 간단한 방법이 있습니다. 이것은 누군가를 도울 수 있습니다.
set @exist_Check := (
select count(*) from information_schema.columns
where TABLE_NAME='YOUR_TABLE'
and COLUMN_NAME='YOUR_COLUMN'
and TABLE_SCHEMA=database()
) ;
set @sqlstmt := if(@exist_Check>0,'alter table YOUR_TABLE drop column YOUR_COLUMN', 'select ''''') ;
prepare stmt from @sqlstmt ;
execute stmt ;
이것이 나처럼 (많은 시행 착오 후에) 누군가에게 도움이되기를 바랍니다.
답변
방금 DROP COLUMN
멱 등성을 만드는 데 도움이되는 재사용 가능한 절차를 만들었습니다 .
-- column_exists:
DROP FUNCTION IF EXISTS column_exists;
DELIMITER $$
CREATE FUNCTION column_exists(
tname VARCHAR(64),
cname VARCHAR(64)
)
RETURNS BOOLEAN
READS SQL DATA
BEGIN
RETURN 0 < (SELECT COUNT(*)
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA` = SCHEMA()
AND `TABLE_NAME` = tname
AND `COLUMN_NAME` = cname);
END $$
DELIMITER ;
-- drop_column_if_exists:
DROP PROCEDURE IF EXISTS drop_column_if_exists;
DELIMITER $$
CREATE PROCEDURE drop_column_if_exists(
tname VARCHAR(64),
cname VARCHAR(64)
)
BEGIN
IF column_exists(tname, cname)
THEN
SET @drop_column_if_exists = CONCAT('ALTER TABLE `', tname, '` DROP COLUMN `', cname, '`');
PREPARE drop_query FROM @drop_column_if_exists;
EXECUTE drop_query;
END IF;
END $$
DELIMITER ;
용법:
CALL drop_column_if_exists('my_table', 'my_column');
예:
SELECT column_exists('my_table', 'my_column'); -- 1
CALL drop_column_if_exists('my_table', 'my_column'); -- success
SELECT column_exists('my_table', 'my_column'); -- 0
CALL drop_column_if_exists('my_table', 'my_column'); -- success
SELECT column_exists('my_table', 'my_column'); -- 0
답변
Chase Seibert의 대답은 작동하지만 여러 스키마가 있으면 SELECT를 변경하려는 경우 다음과 같이 추가합니다.
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
답변
이 문제를 해결하는 가장 간단한 방법은 다음과 같습니다.
-
CREATE new_table AS SELECT id, col1, col2, … (최종 테이블에서 실제로 원하는 열만) FROM my_table;
-
my_table을 old_table로, new_table을 my_table로 이름을 변경합니다.
-
DROP old_table;
또는 필요한 경우 롤백을 위해 old_table을 유지하십시오.
이것은 작동하지만 외래 키는 이동되지 않습니다. 나중에 my_table에 다시 추가해야합니다. my_table을 참조하는 다른 테이블의 외래 키도 수정해야합니다 (새 my_table을 가리킴).
행운을 빕니다…
답변
이 스크립트를 사용하고 열, 스키마 및 테이블 이름을 사용할 수 있습니다.
IF EXISTS (SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName'
AND TABLE_SCHEMA = SchemaName)
BEGIN
ALTER TABLE TableName DROP COLUMN ColumnName;
END;