2009-10-23 10 views
6

Tôi đang tìm kiếm một kịch bản MYSQL duy nhất để chuyển đổi tất cả các tên cột trong một cơ sở dữ liệu thành chữ thường trong một đi ...một kịch bản MYSQL để chuyển đổi các tên cột thành chữ thường

Tôi đã thừa hưởng một cơ sở dữ liệu MYSQL mà có một nhiều tên cột trường hợp hỗn hợp (150 bảng có quy ước đặt tên lạ) và tôi không muốn xem từng bảng theo cách thủ công để làm việc này.

Có ai có tập lệnh như vậy không?

Cảm ơn

Trả lời

2

Bạn có thể giải quyết nhiệm vụ này bằng cách xây dựng một kịch bản, bắt đầu với sản lượng từ tuyên bố này:

SELECT table_name, column_name, data_type 
FROM information_schema.columns 
WHERE table_schema = 'dbname'; 
ORDER BY table_name 

chi tiết về tính năng này có thể được tìm thấy ở đây "MYSQL::The INFORMATION_SCHEMA COLUMNS Table"

Sau đó, bạn có thể sử dụng hàm ALTER TABLE .. ĐỔI để thay đổi tên của các cột

ví dụ:

ALTER TABLE mytable CHANGE old_name new_name varchar(5); 

Xem thêm "MYSQL::ALTER TABLE Syntax"

datatype khác nhau có những yêu cầu khác nhau, do đó bạn cần sự đoàn:

SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(character_maximum_length)||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('CHAR', 'VARCHAR') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('INTEGER') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||','||CHAR(numeric_scale)|');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('FLOAT') 
    ORDER BY table_name 
    UNION 
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||');' AS Line 
    FROM information_schema.columns 
    WHERE table_schema = dbname and datatype in ('DATE') 
    ORDER BY table_name 
+0

Cảm ơn, điều này đã cho tôi đủ gần .... – Rippo

+0

Tôi không thể kiểm tra nó nhưng tôi vui vì tôi đã đóng :) – Adrian

+0

Chúng tôi sẽ nhận được lỗi này "LRI 1054 (42S22): Cột không xác định 'datatype' trong 'danh sách trường' "trong mysql 5.7. Sử dụng 'data_type', nhưng không có 'datatype' – user3081809

6

Trong trường hợp bất cứ ai muốn này dưới đây là một ví dụ về truy vấn hoàn thành, xin vui lòng kiểm tra trước khi bạn sử dụng .....

CHỈNH SỬA GIẢI PHÁP HOÀN THÀNH ĐƯỢC YÊU CẦU

SELECT CONCAT(
'ALTER TABLE ', table_name, 
' CHANGE ', column_name, ' ', 
LOWER(column_name), ' ', column_type, ' ', extra, 
CASE WHEN IS_NULLABLE = 'YES' THEN ' NULL' ELSE ' NOT NULL' END, ';') AS line 
FROM information_schema.columns 
WHERE table_schema = '<DBNAME>' 
AND data_type IN ('char', 'varchar','INT', 'TINYINT', 'datetime','text','double','decimal') 
ORDER BY line; 

HTH ai đó trong tương lai ... BTW quan điểm cũng kịch bản ở đây để bạn có thể cần phải đưa họ ra khỏi mã SQL cuối cùng của bạn

+0

Nếu bạn có một giải pháp hoàn chỉnh, bạn nên thêm nó vào câu hỏi của mình để người khác có thể tìm thấy nó dễ dàng hơn – Adrian

+1

ở đó, nó không hoàn hảo nhưng đủ gần! – Rippo

+0

Để giảm cử tri, hãy tự hỏi tại sao bạn bỏ phiếu. bất kỳ ý kiến ​​được chào đón, nhờ – Rippo

6

Bạn có thể đổi tên tất cả các bảng và cột tên thành chữ thường bởi áp dụng các biểu thức chính quy sau để một bãi chứa SQL (ví dụ, các bãi chứa được tạo ra bởi mysqldump):

s/`\(\w\+\)`/\L&/g 

này hoạt động bởi vì tất cả bảng và cột tên được bọc bởi `` (backticks). Tốt hơn là chỉ thực hiện điều này trên lược đồ, tách biệt với dữ liệu (chỉ làm việc với các cấu trúc bảng và sau đó thực hiện các chèn).

Để làm điều này trong Vim, mở bãi SQL và nhập lệnh sau:

:%s/`\(\w\+\)`/\L&/g 

Hoặc làm điều đó từ dòng lệnh sử dụng sed:

sed 's/`\(\w\+\)`/\L&/g' input.sql > output.sql 

Nếu bạn cần phải làm điều đó lặp lại, lưu trữ biểu thức trong tệp văn bản và gọi cụm từ đó như sau:

sed -f regex.txt input.sql > output.sql 
+0

Điều này đã giúp tôi SO MUCH. Cảm ơn bạn! – aendrew

+0

Cảm ơn d3vid cho phiên bản. Nó rất hữu ích bây giờ. – lepe

3

Giải pháp được đề xuất bởi lepe thực sự là cách an toàn duy nhất để đi. Các phương thức kịch bản quá nguy hiểm, dễ xuất hoặc xử lý định nghĩa dữ liệu sai. Tất cả các tập lệnh ví dụ trên đều loại bỏ một số loại dữ liệu, vì vậy chúng không đầy đủ.

Tôi đã làm một sqldump đặt backticks xung quanh tên bảng và cột, sau đó sử dụng Notepad ++ để tìm kiếm trên (`. *`) Và thay thế bằng \ L \ 1. Điều đó làm cho tất cả các tên bảng và cột của tôi trở nên thấp hơn.

Sau đó, tôi sao lưu cơ sở dữ liệu của mình, xóa sạch tất cả các bảng và sau đó thực hiện tệp .sql của tôi để xây dựng lại. Tôi không lo lắng về việc làm cấu trúc tách biệt với dữ liệu khi tôi thấy không có sự xuất hiện của biểu tượng backtick trong bất kỳ dữ liệu nào của tôi.

Trong trường hợp của tôi, tôi cần tất cả các tên cột của tôi thấp hơn vì môi trường phát triển của tôi tự động chuyển đổi first_name thành First Name: làm nhãn trường để nhập dữ liệu. Nếu tôi để chúng dưới dạng mũ (mà tôi thừa kế), chúng sẽ chuyển thành TÊN ĐẦU TIÊN mà không phải là thứ tôi muốn, tôi phải thay đổi tất cả các nhãn trường của mình.