查看完整版本: 写了一个MYSQL的行转列的存储过程

php 2007-11-7 09:01

写了一个MYSQL的行转列的存储过程

网上的都是一些静态的,用CASE WHEN结构实现。所以我写了一个动态的。




SP 代码:

[color=#000000]DELIMITER $$

[color=#0000ff]DROP[/color] PROCEDURE IF EXISTS [color=#ff00ff]`test`[/color][color=#0000cc].[/color][color=#ff00ff]`sp_row_column_wrap`[/color][color=#ff00ff]$[/color][color=#ff00ff]$[/color]

[color=#0000ff]CREATE[/color] DEFINER[color=#0000cc]=[/color][color=#ff00ff]`root`[/color][color=#0000ff]@[/color][color=#ff00ff]`localhost`[/color] PROCEDURE [color=#ff00ff]`sp_row_column_wrap`[/color][color=#0000cc]([/color][color=#0000ff]IN[/color] $schema_name [color=#ff0000]varchar[/color][color=#0000cc]([/color]64[color=#0000cc])[/color][color=#0000cc],[/color]
[color=#0000ff]IN[/color] $table_name [color=#ff0000]varchar[/color][color=#0000cc]([/color]64[color=#0000cc])[/color][color=#0000cc])[/color]
BEGIN
  declare cnt [color=#ff0000]int[/color][color=#0000cc]([/color]11[color=#0000cc])[/color][color=#0000cc];[/color]
  declare $table_rows [color=#ff0000]int[/color][color=#0000cc]([/color]11[color=#0000cc])[/color][color=#0000cc];[/color]
  declare i [color=#ff0000]int[/color][color=#0000cc]([/color]11[color=#0000cc])[/color][color=#0000cc];[/color]
  declare j [color=#ff0000]int[/color][color=#0000cc]([/color]11[color=#0000cc])[/color][color=#0000cc];[/color]
  declare s [color=#ff0000]int[/color][color=#0000cc]([/color]11[color=#0000cc])[/color][color=#0000cc];[/color]
  declare str [color=#ff0000]varchar[/color][color=#0000cc]([/color]255[color=#0000cc])[/color][color=#0000cc];[/color]
  -- Get the column number of the [color=#0000ff]table[/color]
  [color=#0000ff]select[/color] [color=#0000ff]count[/color][color=#0000cc]([/color]1[color=#0000cc])[/color] [color=#0000ff]from[/color] information_schema[color=#0000cc].[/color]columns [color=#0000ff]where[/color] table_schema[color=#0000cc]=[/color][color=#0000cc]$[/color]schema_name [color=#ff0000]and[/color] table_name[color=#0000cc]=[/color][color=#0000cc]$[/color]table_name [color=#0000ff]into[/color] cnt[color=#0000cc];[/color]
  -- Get the row number of the [color=#0000ff]table[/color]
  [color=#0000ff]select[/color] table_rows [color=#0000ff]from[/color] information_schema[color=#0000cc].[/color]tables [color=#0000ff]where[/color] table_schema [color=#0000cc]=[/color] $schema_name [color=#ff0000]and[/color] table_name[color=#0000cc]=[/color][color=#0000cc]$[/color]table_name [color=#0000ff]into[/color] $table_rows[color=#0000cc];[/color]
  -- Check whether the [color=#0000ff]table[/color] exists [color=#ff0000]or[/color] [color=#ff0000]not[/color]
  [color=#0000ff]drop[/color] [color=#0000ff]table[/color] if exists test[color=#0000cc].[/color]temp[color=#0000cc];[/color]
  [color=#0000ff]create[/color] [color=#0000ff]table[/color] if [color=#ff0000]not[/color] exists test[color=#0000cc].[/color]temp [color=#0000cc]([/color][color=#ff00ff]`1`[/color] [color=#ff0000]varchar[/color][color=#0000cc]([/color]255[color=#0000cc])[/color] [color=#ff0000]not[/color] [color=#0000ff]null[/color][color=#0000cc])[/color][color=#0000cc];[/color]
  -- loop1 start
  [color=#0000ff]set[/color] i [color=#0000cc]=[/color] 0[color=#0000cc];[/color]
  loop1:loop
    if i [color=#0000cc]=[/color] $table_rows-1 [color=#0000ff]then[/color]
      leave loop1[color=#0000cc];[/color]
    [color=#0000ff]end[/color] if[color=#0000cc];[/color]
    [color=#0000ff]set[/color] [color=#0000ff]@[/color][color=#008080]stmt1[/color] [color=#0000cc]=[/color] [color=#ff0000]concat[/color][color=#0000cc]([/color][color=#ff00ff]'alter table test.temp add `'[/color][color=#0000cc],[/color]i[color=#0000cc]+[/color]2[color=#0000cc],[/color][color=#ff00ff]'` varchar(255) not null'[/color][color=#0000cc])[/color][color=#0000cc];[/color]
    prepare s1 [color=#0000ff]from[/color] [color=#0000ff]@[/color][color=#008080]stmt1[/color][color=#0000cc];[/color]
    execute s1[color=#0000cc];[/color]
    deallocate prepare s1[color=#0000cc];[/color]
    [color=#0000ff]set[/color] i [color=#0000cc]=[/color] i [color=#0000cc]+[/color] 1[color=#0000cc];[/color]
  [color=#0000ff]end[/color] loop loop1[color=#0000cc];[/color]
  -- loop1 [color=#0000ff]end[/color][color=#0000cc];[/color]
  [color=#0000ff]set[/color] s [color=#0000cc]=[/color] 0[color=#0000cc];[/color]
  -- loop2 start
  loop2:loop
  -- leave loop2
    if s[color=#0000cc]=[/color]cnt [color=#0000ff]then[/color]
      leave loop2[color=#0000cc];[/color]
    [color=#0000ff]end[/color] if[color=#0000cc];[/color]
    [color=#0000ff]set[/color] [color=#0000ff]@[/color][color=#008080]stmt2[/color] [color=#0000cc]=[/color] [color=#ff0000]concat[/color][color=#0000cc]([/color][color=#ff00ff]'select column_name from information_schema.columns where table_schema="'[/color][color=#0000cc],[/color][color=#0000cc]$[/color]schema_name[color=#0000cc],[/color]
                        [color=#ff00ff]'" and table_name="'[/color][color=#0000cc],[/color][color=#0000cc]$[/color]table_name[color=#0000cc],[/color][color=#ff00ff]'" limit '[/color][color=#0000cc],[/color]s[color=#0000cc],[/color][color=#ff00ff]',1 into @temp;'[/color][color=#0000cc])[/color][color=#0000cc];[/color]
    prepare s2 [color=#0000ff]from[/color] [color=#0000ff]@[/color][color=#008080]stmt2[/color][color=#0000cc];[/color]
    execute s2[color=#0000cc];[/color]
    deallocate prepare s2[color=#0000cc];[/color]
    [color=#0000ff]set[/color] j[color=#0000cc]=[/color]0[color=#0000cc];[/color]
    [color=#0000ff]set[/color] str [color=#0000cc]=[/color] [color=#ff00ff]' select '[/color][color=#0000cc];[/color]
    -- Loop3 start
    loop3:loop
      if j [color=#0000cc]=[/color] $table_rows [color=#0000ff]then[/color]
        leave loop3[color=#0000cc];[/color]
      [color=#0000ff]end[/color] if[color=#0000cc];[/color]
      [color=#0000ff]set[/color] [color=#0000ff]@[/color][color=#008080]stmt3[/color] [color=#0000cc]=[/color] [color=#ff0000]concat[/color][color=#0000cc]([/color][color=#ff00ff]'select '[/color][color=#0000cc],[/color][color=#0000ff]@[/color][color=#008080]temp[/color][color=#0000cc],[/color][color=#ff00ff]' from '[/color][color=#0000cc],[/color][color=#0000cc]$[/color]schema_name[color=#0000cc],[/color][color=#ff00ff]'.'[/color][color=#0000cc],[/color][color=#0000cc]$[/color]table_name[color=#0000cc],[/color][color=#ff00ff]' limit '[/color][color=#0000cc],[/color]j[color=#0000cc],[/color][color=#ff00ff]',1 into @temp2;'[/color][color=#0000cc])[/color][color=#0000cc];[/color]
      prepare s3 [color=#0000ff]from[/color] [color=#0000ff]@[/color][color=#008080]stmt3[/color][color=#0000cc];[/color]
      execute s3[color=#0000cc];[/color]
      [color=#0000ff]set[/color] str [color=#0000cc]=[/color] [color=#ff0000]concat[/color][color=#0000cc]([/color]str[color=#0000cc],[/color][color=#ff00ff]'"'[/color][color=#0000cc],[/color][color=#0000ff]@[/color][color=#008080]temp2[/color][color=#0000cc],[/color][color=#ff00ff]'"'[/color][color=#0000cc],[/color][color=#ff00ff]','[/color][color=#0000cc])[/color][color=#0000cc];[/color]
      deallocate prepare s3[color=#0000cc];[/color]
      [color=#0000ff]set[/color] j [color=#0000cc]=[/color] j[color=#0000cc]+[/color]1[color=#0000cc];[/color]
    [color=#0000ff]end[/color] loop loop3[color=#0000cc];[/color]
    [color=#0000ff]set[/color] str [color=#0000cc]=[/color] [color=#ff0000]left[/color][color=#0000cc]([/color]str[color=#0000cc],[/color][color=#0000ff]length[/color][color=#0000cc]([/color]str[color=#0000cc])[/color][color=#0000cc]-[/color]1[color=#0000cc])[/color][color=#0000cc];[/color]
    -- [color=#0000ff]insert[/color] new data [color=#0000ff]into[/color] [color=#0000ff]table[/color]
    [color=#0000ff]set[/color] [color=#0000ff]@[/color][color=#008080]stmt4[/color] [color=#0000cc]=[/color] [color=#ff0000]concat[/color][color=#0000cc]([/color][color=#ff00ff]'insert into test.temp'[/color][color=#0000cc],[/color]str[color=#0000cc],[/color][color=#ff00ff]';'[/color][color=#0000cc])[/color][color=#0000cc];[/color]
    prepare s4 [color=#0000ff]from[/color] [color=#0000ff]@[/color][color=#008080]stmt4[/color][color=#0000cc];[/color]
    execute s4[color=#0000cc];[/color]
    deallocate prepare s4[color=#0000cc];[/color]
    [color=#0000ff]set[/color] s[color=#0000cc]=[/color]s[color=#0000cc]+[/color]1[color=#0000cc];[/color]
  [color=#0000ff]end[/color] loop loop2[color=#0000cc];[/color]
[color=#0000ff]END[/color][color=#0000ff]$[/color][color=#0000ff]$[/color]

DELIMITER [color=#0000cc];[/color][/color]

以下是测试结果:

======
select * from a;
select * from b;
select * from salary;

call sp_row_column_wrap('test','a');
select * from test.temp;
call sp_row_column_wrap('test','b');
select * from test.temp;
call sp_row_column_wrap('test','salary');
select * from test.temp;


query result(2 records)

[table][tr][td]aid[/td][td]title[/td][/tr][tr][td]1[/td][td]111[/td][/tr][tr][td]2[/td][td]222[/td][/tr][/table]

query result(3 records)

[table][tr][td]bid[/td][td]aid[/td][td]image[/td][td]time[/td][/tr][tr][td]1[/td][td]2[/td][td]1.gif[/td][td]2007-08-08[/td][/tr][tr][td]2[/td][td]2[/td][td]2.gif[/td][td]2007-08-09[/td][/tr][tr][td]3[/td][td]2[/td][td]3.gif[/td][td]2007-08-08[/td][/tr][/table]

query result(7 records)

[table][tr][td]id[/td][td]cost[/td][td]des[/td][td]Autoid[/td][/tr][tr][td]1[/td][td]10[/td][td]aaaa[/td][td]1[/td][/tr][tr][td]1[/td][td]15[/td][td]bbbb[/td][td]2[/td][/tr][tr][td]1[/td][td]20[/td][td]cccc[/td][td]3[/td][/tr][tr][td]2[/td][td]80[/td][td]aaaa[/td][td]4[/td][/tr][tr][td]2[/td][td]100[/td][td]bbbb[/td][td]5[/td][/tr][tr][td]2[/td][td]60[/td][td]dddd[/td][td]6[/td][/tr][tr][td]3[/td][td]500[/td][td]dddd[/td][td]7[/td][/tr][/table]
query result(2 records)

[table][tr][td]1[/td][td]2[/td][/tr][tr][td]1[/td][td]2[/td][/tr][tr][td]111[/td][td]222[/td][/tr][/table]
query result(4 records)


[table][tr][td]1[/td][td]2[/td][td]3[/td][/tr][tr][td]1[/td][td]2[/td][td]3[/td][/tr][tr][td]2[/td][td]2[/td][td]2[/td][/tr][tr][td]1.gif[/td][td]2.gif[/td][td]3.gif[/td][/tr][tr][td]2007-08-08[/td][td]2007-08-09[/td][td]2007-08-08[/td][/tr][/table]

query result(4 records)

[table][tr][td]1[/td][td]2[/td][td]3[/td][td]4[/td][td]5[/td][td]6[/td][td]7[/td][/tr][tr][td]1[/td][td]1[/td][td]1[/td][td]2[/td][td]2[/td][td]2[/td][td]3[/td][/tr][tr][td]10[/td][td]15[/td][td]20[/td][td]80[/td][td]100[/td][td]60[/td][td]500[/td][/tr][tr][td]aaaa[/td][td]bbbb[/td][td]cccc[/td][td]aaaa[/td][td]bbbb[/td][td]dddd[/td][td]dddd[/td][/tr][tr][td]1[/td][td]2[/td][td]3[/td][td]4[/td][td]5[/td][td]6[/td][td]7[/td][/tr][/table]

[[i] 本帖最后由 php 于 2007-11-7 09:11 编辑 [/i]]
页: [1]
查看完整版本: 写了一个MYSQL的行转列的存储过程