2016-06-20 20 views
0

我已经使用phpmyadmin将csv表导入到sql数据库中。我猜默认的格式是十进制(8,5),或者至少是它的出现方式。似乎矫枉过正,我认为我可以减少到4,1。问题是有大约470个领域。我知道如何一次更换一个,但这需要很长时间。有更快的方法吗?一次修改多个数据库列的格式

回答

0

我只有Sql Server 2008 R2,但似乎MySQL解决方案可能类似。我试图尽可能地将它与MySQL保持一致,但没有MySQL引擎我无法检查它...所以对于它的价值,这是我的脚本(在Sql Server中测试):

-- I believe this is 'CREATE TEMPORARY TABLE' in MySql 
create table #tbl 
(
    ownerName sysname -- `sysname` is nvarchar(128) the max identifier length 
    , tableName sysname 
    , colName sysname 
    , colType sysname 
    , colPrecision int 
    , colScale int 
) 
insert #tbl 
select table_schema, table_name, column_name, data_type, numeric_precision, numeric_scale 
FROM information_schema.columns 
where data_type = 'decimal' and numeric_precision = 8 and numeric_scale = 5 

-- Note: It is 'MODIFY COLUMN' in MySQL 
declare @newPrecision int = 4, @newScale int = 1 
DECLARE @sql varchar(max) = '' 
select @sql = @sql + CHAR(13) + CHAR(10) + 'ALTER TABLE ' + ownerName + '.' + tableName + ' ALTER COLUMN ' 
    + colName + ' decimal(' + cast(@newPrecision as varchar(max)) + ',' + cast(@newScale as varchar(max)) + ')' 
from #tbl 
/** 
    -- In MySql, GROUP_CONCAT() may work 
    select @sql = GROUP_CONCAT('ALTER TABLE ' + ownerName + '.' + tableName + ' MODIFY COLUMN ' 
    + colName + ' decimal(' + cast(@newPrecision as varchar(max)) + ',' + cast(@newScale as varchar(max)) + ')' SEPARATOR ' ') 
    from #tbl 
**/ 

print @sql 
execute (@sql) 
0

我从来没有在之前使用过SqlFiddle,因此认为现在是开始的好时机,专门为MySQL 5.6提供完整的答案。请参阅http://sqlfiddle.com/#!9/19f46/1

在“构建架构”面板的底部,选择Delimiter = [//]。 SqlFiddle使用它来决定何时向MySQL发送一段代码。这是必要的,因为CREATE PROCEDURE必须作为一个块发送出去。如果您使用默认的Delimiter = [; ],那么它只会发送创建程序的一部分,直到它找到的第一个;

cols选择具有您想要更改的精度和标度的decimal类型的列。目前根据OP要求将其硬编码为8和5,但根据需要进行更改以仅标识要修改的列。在进行表修改以运行此选择以验证您将要修改的列之前,这将是一个好主意。

存储过程exec_multiple使用表cols来生成然后动态执行的ALTER TABLE语句。

EXECUTE一次只处理一条语句,因此您需要遍历cols的行并分别应用每个ALTER TABLEcols中的auto_increment列id允许您在不使用游标的情况下轮流选择每一行。

test_log捕获您可能想要在构建模式完成后检查的任何调试信息。

以下内容位于左侧的“构建架构”面板中。 所有的逻辑都需要在此面板中,因为SqlFiddle不允许在“运行SQL”面板中使用数据定义语言或表插入/更新/删除语句。

create table if not exists cols 
(
    id int auto_increment primary key 
    , ownerName varchar(128) 
    , tblName varchar(128) 
    , colName varchar(128) 
    , colType varchar(128) 
    , colPrecision int 
    , colScale int 
) // 

create table if not exists test_table 
(
    testDecimal1 decimal(8,5) 
    , testDecimal2 decimal(8,5) 
) // 

create table if not exists test_table2 
(
    testDecimal3 decimal(8,5) 
    , testDecimal4 decimal(8,5) 
) // 

create table if not exists test_log 
(
    msg varchar(1024) 
) // 

INSERT INTO cols 
(ownerName, tblName, colName, colType, colPrecision, colScale) 
SELECT TABLE_SCHEMA, `TABLE_NAME`, COLUMN_NAME, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE DATA_TYPE = 'decimal' AND NUMERIC_PRECISION = 8 AND NUMERIC_SCALE = 5 // 

insert test_log(msg) select database() // 

CREATE PROCEDURE `exec_multiple` (newPrecision int, newScale int) 
BEGIN 
    declare n int; 
    declare nrows int; 
    declare sql_stmt varchar(1024); 
    set n = 1; 
    select count(*) from cols into nrows; 

    while n <= nrows do 

     select CONCAT('ALTER TABLE ' 
     , ownerName, '.', tblName, ' MODIFY COLUMN ' 
     , colName, ' decimal(', newPrecision, ',' 
     , newScale, ')') into sql_stmt from `cols` where id = n; 

     SET @sql_stmt := sql_stmt; -- not sure why this is necessary 

     insert test_log(msg) select @sql_stmt; 

     PREPARE dynamic_statement FROM @sql_stmt; 
     EXECUTE dynamic_statement; 
     DEALLOCATE PREPARE dynamic_statement; 

     set n = n + 1; 
    end while; 
END // 

call exec_multiple(4, 1) // 

这正好在运行SQL面板右侧

select * from test_log; 

SELECT TABLE_SCHEMA, `TABLE_NAME`, COLUMN_NAME, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE DATA_TYPE = 'decimal' 
; 

select * from cols; 
+1

您的报价:' - 不知道这是为什么necessary' ...原因有二:(1)你没有这样做一个concat最初到一个用户变量。 (2)在你引用的那一行上,mysql是finicky,它不喜欢局部变量,但喜欢用户变量。 – Drew

+0

@德鲁 - 我希望有人会对此发表评论!这是我的第一个MySql脚本。我只想在存储过程中使用局部变量,但是在这种情况下,感谢您确认用户变量是必需的。基本逻辑与Sql Server类似,但变量处理需要一段时间才能正常工作。 –

+0

是的,手册页也是如此幻想,对吧?! – Drew