2016-09-20 7 views
0

잘못된 데이터 정렬이있는 데이터베이스 테이블에 저장된 함수가 여러 개인 경우 (데이터 정렬 오류가 불법적으로 혼합되어 나타나는 것처럼 보입니다). 필자가 읽은 바에 따르면, "자리에서"기능을위한 데이터 정렬을 변경할 수는 없습니다. 데이터를 삭제하고 다시 만들어야합니다.mysql : 대량의 새로운 데이터 정렬을 사용하여 함수를 삭제하고 다시 작성하십시오.

새로운 일괄 처리를 사용하여 삭제하고 다시 만드는 방법을 찾고 있습니다. 즉, 기존 함수 정의를 DB에서 직접 "읽고", 데이터 정렬을 변경하고 다시 작성할 수 있어야합니다. 프로세스의 구성 부분을 알고 기능에 따라 기능을 수행 할 수 있지만 DB 전체에서 대량으로 효율적으로 수행 할 수있는 방법을 찾는 데 어려움을 겪고 있습니다.

답변

1

다음 스크립트는 그들이 지금 SHOW CREATE FUNCTION 유사하다 당신이 데이터베이스의 모든 기능을 다시하는 스크립트를 생성하지만, 실제 결과 집합으로, 동시에 모든 기능에 대한 것입니다. 당신이 bash가 명령 행 클라이언트를 필요로하는 것 때문에

select sql_stmt 
from (
    select p.db, p.name, p.type, 1 as intord, p.character_set_client, 
    concat('drop ',p.type, ' if exists ', p.db,'.`', p.name,'`;') as sql_stmt 
    from mysql.proc p 
    union all 
    select p.db, p.name, p.type, 2 as intord, p.character_set_client, 
    'delimiter $$' as sql_stmt 
    from mysql.proc p 
    union all 
    select p.db, p.name, p.type, 3 as intord, p.character_set_client, 
    concat('CREATE DEFINER=`',replace(p.definer,'@','`@`'),'` ', 
     p.type, 
     ' ',p.db,'.`',p.name, 
     '`(',convert(p.param_list USING utf8),') ', 
     case 
     when length(p.returns) > 1 
     then concat(' RETURNS ', convert(p.returns USING utf8)) 
     else '' 
     end, ' \n', 
     case 
     when p.is_deterministic = 'YES' then '\tDETERMINISTIC\n' 
     else '' 
     end, 
     case 
     when p.language = 'SQL' THEN '' 
     else concat('\tLANGUAGE ',p.language, '\n') 
     end, 
     case 
     when p.sql_data_access = 'CONTAINS_SQL' THEN '' 
     when p.sql_data_access = 'NO_SQL' THEN '\tNO SQL\n' 
     when p.sql_data_access = 'READS_SQL_DATA' THEN '\tREADS SQL DATA\n' 
     when p.sql_data_access = 'MODIFIES_SQL_DATA' THEN '\tMODIFIES SQL DATA\n' 
     else concat('\t',replace(p.sql_data_access,'_', ' '), '\n') 
     end, 
     case when p.security_type <> 'DEFINER' 
     then concat('\tSQL SECURITY ', p.security_type, '\n') 
     else '' 
     end, 
     case when p.comment <> '' 
     then concat('\tCOMMENT ''', 
      replace(replace(p.comment,'''',''''''),'\n','\\n') 
      ,'''') 
     else '' 
     end, '\n', 
     convert(p.body USING utf8), 
     '$$' 
    ) as sql_stmt 
    from mysql.proc p 
    union all 
    select p.db, p.name, p.type, 4 as intord, p.character_set_client, 
    'delimiter ;' as sql_stmt 
    from mysql.proc p 

) sql_stmts 
where db = <yourdbname> 
and type = 'function' 
and character_set_client = 'utf8' 
order by db, name, type, intord; 

이 결과는 형태

drop function if exists a; 
delimiter $$ 
CREATE DEFINER=`root`@`127.0.0.1` FUNCTION yourdb.`a`(... 
delimiter ; 
drop function if exists b; 
delimiter $$ 
... 

에있을 것입니다, 당신은 예를 들어, 스크립트를 실행할 수 있습니다

mysql -u root -p -N -r <thisscript.sql> recreatefunctions.sql 

매개 변수 -N-r으로이 결과에 표시 할 수있는 헤더를 방지하고 우리가 실행 스크립트로 직접 결과를 처리 할 때문에 '\n'\n의 번역을 방지한다.

예를 들어 실행하면 Workbench에서 결과 (Copy rows (unquoted))를 새 창에 복사하십시오.

그런 다음 생성 된 스크립트를 필요에 맞게 편집기에서 편집하거나 스크립트 (예 : charset latin1charset utf8 또는 원하는대로 바꿉니다.

위의 스크립트에서이 작업을 수행하는 것이 더 쉽습니다. 조정해야 할 사항을 자세히 설명하지는 않았지만 예를 들어 스크립트를 수정하고

then concat(' RETURNS ', convert(p.returns USING utf8)) 

에 의해

then concat(' RETURNS ', replace(convert(p.returns USING utf8),'latin1', 'utf8')) 
파일을 편집 한 후 마지막으로 당신의 기능을 업데이트하려면

, 당신이 사용할 수있는 대체 할 수있는, latin1에서 utf8에 반환 매개 변수의 문자 집합을 변경하려면

mysql -u root -p < recreatefunctions.sql 

스크립트는 가정 그 코드합니다 (mysql.proc 테이블에 BLOB 필드, 당신은 변경하지 문자 집합)은 utf8으로 저장됩니다. 이것은 대개의 경우이지만 예방책으로 다른 곳에서도 작동해야하지만 utf8으로 저장된 함수 만 읽고 (대체합니다). 표 mysql.proc, 열 character_set_client에서 확인해야합니다. 그런 다음 convert(p.param_list USING utf8)), convert(p.returns USING utf8))convert(p.body USING utf8)을 올바른 인코딩으로 바꾸거나 여러 인코딩을 사용하는 경우 case- 문구를 사용할 수 있습니다.

그런데 시도하기 전에 동적 SQL 문에서 create function을 사용할 수 없으므로 mysql (내장 프로 시저의 동적 SQL)에서 완전히 수행 할 수 없습니다.

그런데, 그것을 시도하기 전에 백업을 만드십시오!

+0

예, show create 함수를 통해 함수를 가져 오는 것은 현재까지입니다. 나는 bash에서 스크립팅을하고 있으며, 쿼리 결과에서 create function "column"을 추출하는 쉬운 방법이 없다. 가장 큰 어려움이있는 곳인 것 같습니다. – lcdservices

+0

@lcdservices'show create function'이 필요없는 버전을 썼습니다. 필요한 모든 코드를 다시 작성하여 필요에 맞게 수정할 수있는 코드를 작성합니다 (또는 요구 사항에 따라 스크립트를 수정에 적용 할 수 있습니다. 정확히 바꿀 내용을 설명하지 않았습니다). – Solarflare

+0

와우 - 큰 도움이됩니다. 감사! 지금 당장 몇 가지 테스트를 해보겠습니다. – lcdservices