语句如下:
DROP PROCEDURE IF EXISTS p_get_attribute_csv_data;
CREATE PROCEDURE p_get_attribute_csv_data
(
  in p_attributeType_name varchar(500)
)
BEGIN    DECLARE temp_type_id int (11);
    DECLARE tp_table_count int (2);
    declare tp_sqlcode varchar(1000);
    
    SELECT tb_type.type_id INTO temp_type_id from tb_type WHERE tb_type.type_name = p_attributeType_name;    SET @ColumnCode=''; 
    SELECT @ColumnCode := CONCAT(@ColumnCode,'max(IF(attribute_name=\'',attribute_name,'\'',',attribute_name, \'\'))  AS ''', attribute_name ,'','\',')  
    FROM tb_attribute where tb_attribute.type_id = temp_type_id ORDER BY tb_attribute.index_id;    drop table if exists tb_temp_attribute_info; -- 先删除临时表
    
-- 确定临时表已不存在
    select count(*) into tp_table_count from information_schema.tables where table_schema='ofigo_cm' and table_name='tb_temp_attribute_info';
    if tp_table_count <> 0 then
      select * from tb_temp_attribute_info ;
    End if;
    
-- 创建新的临时表
    SET @Code = '';
    SET @Code=CONCAT('CREATE TEMPORARY TABLE tb_temp_attribute_info SELECT  ',
 IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');
    
-- 打印出每次的语句,确认语句每次都不同
    set tp_sqlcode = '';
    set tp_sqlcode = CONCAT('CREATE temporary TABLE tb_temp_attribute_info SELECT  ',
 IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');
 select tp_sqlcode;-- 执行动态SQL,得到不同临时表
    PREPARE sqlCode FROM @Code;
    EXECUTE sqlCode;

    SELECT * from tb_temp_attribute_info; -- 得到临时表的结果
END;目前的现象是,第一次执行没有问题,改变参数后再执行,就会报未知列异常,如:Unknown column 'tb_temp_attribute_info.Name' in 'field list'。该过程的目的是希望根据传入的参数,创建出带有不同字段的临时表,并返回这个临时表。注意:上面的过程在Toad for MySql中执行是正常的,但在Navicat Premium 或者 ADO.NET中执行是异常的!
希望哪位高人,不吝赐教下小弟!先谢谢了!

解决方案 »

  1.   

    表结构是什么,怎么调用的DELIMITER $$
    DROP PROCEDURE IF EXISTS p_get_attribute_csv_data$$
    CREATE PROCEDURE p_get_attribute_csv_data(IN p_attributeType_name VARCHAR(500))
    BEGIN
      DECLARE temp_type_id INT (11);
      DECLARE tp_table_count INT (2);
      DECLARE tp_sqlcode VARCHAR(1000);
      SELECT tb_type.type_id INTO temp_type_id FROM tb_type WHERE tb_type.type_name = p_attributeType_name;
      SET @ColumnCode=''; 
      SELECT @ColumnCode := CONCAT(@ColumnCode,'max(IF(attribute_name=\'',attribute_name,'\'',',attribute_name, \'\')) AS ''', attribute_name ,'','\',')   
      FROM tb_attribute WHERE tb_attribute.type_id = temp_type_id ORDER BY tb_attribute.index_id;  DROP TABLE IF EXISTS tb_temp_attribute_info; -- 先删除临时表
        
    -- 确定临时表已不存在
      SELECT COUNT(*) INTO tp_table_count FROM information_schema.TABLES WHERE table_schema='ofigo_cm' AND table_name='tb_temp_attribute_info';
      IF tp_table_count <> 0 THEN
      SELECT * FROM tb_temp_attribute_info ;
      END IF;
        
    -- 创建新的临时表
      SET @CODE = '';
      SET @CODE=CONCAT('CREATE TEMPORARY TABLE tb_temp_attribute_info SELECT ',
    IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');
        
    -- 打印出每次的语句,确认语句每次都不同
      SET tp_sqlcode = '';
      SET tp_sqlcode = CONCAT('CREATE temporary TABLE tb_temp_attribute_info SELECT ',
    IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');
     SELECT tp_sqlcode;-- 执行动态SQL,得到不同临时表 
      PREPARE sqlCode FROM @CODE;
      EXECUTE sqlCode;  SELECT * FROM tb_temp_attribute_info; -- 得到临时表的结果
    END $$
    DELIMITER ;
      

  2.   

    drop table if exists tb_temp_attribute_info;->
    drop TEMPORARY table if exists tb_temp_attribute_info;
      

  3.   

    select count(*) into tp_table_count from information_schema.tables where table_schema='ofigo_cm' and table_name='tb_temp_attribute_info';
      if tp_table_count <> 0 then
      select * from tb_temp_attribute_info ;
      End if;
    这个部分不对吧,换成 select * from tb_temp_attribute_info  if exists tb_temp_attribute_info ;
      

  4.   

    将 set tp_sqlcode = CONCAT('CREATE temporary TABLE tb_temp_attribute_info SELECT ',
    IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');换成 set tp_sqlcode = CONCAT('drop temporary table if exists tb_temp_attribute_info; CREATE temporary TABLE tb_temp_attribute_info SELECT ',
    IFNULL(LEFT(@ColumnCode,LENGTH(@ColumnCode)-1),'*'),' FROM tb_attribute;');
      

  5.   

    临时表将在你连接MySQL期间存在。当你断开时,MySQL将自动删除表并释放所用的空间。
    当然你可以在仍然连接的时候删除表并释放空间。 
      

  6.   


    DROP TEMPORARY TABLE IF EXISTS tb_temp_attribute_info;
      

  7.   

    回复:
    2楼、4楼、8楼的想法我都试过,都不行!5楼说的概念我知道,但事实就是这么妖孽!6楼、7楼我知所以用动态SQL就是因为每次参数变化后得到的字段都是不同的,用物理表,还是动态创建的,是否可行呢?
    9楼的大哥,我没有用线程!10楼,测试问题依旧!
      

  8.   

    将你用到的表,建表及插入记录的SQL语句贴出来
      

  9.   

    相关的表和测试数据:
    /*
    Navicat MySQL Data TransferSource Server         : Localhost
    Source Server Version : 50151
    Source Host           : localhost:3306Target Server Type    : MYSQL
    Target Server Version : 50151
    File Encoding         : 65001Date: 2011-02-25 15:15:11
    */SET FOREIGN_KEY_CHECKS=0;
    -- ----------------------------
    -- Table structure for `tb_type`
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_type`;
    CREATE TABLE `tb_type` (
      `type_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '种类id',
      `type_name` varchar(100) COLLATE utf8_unicode_ci NOT NULL COMMENT '种类名称',
      `type_memo` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '种类説明',
      PRIMARY KEY (`type_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;-- ----------------------------
    -- Records of tb_type
    -- ----------------------------
    INSERT INTO tb_type VALUES ('1', 'TT', null);
    INSERT INTO tb_type VALUES ('2', 'YY', null);
    INSERT INTO tb_type VALUES ('3', 'SS', null);
    INSERT INTO tb_type VALUES ('4', 'TEST\'TR', null);
    INSERT INTO tb_type VALUES ('5', 'EE', null);
    INSERT INTO tb_type VALUES ('6', 'Test_1', 'test');
    SET FOREIGN_KEY_CHECKS=0;
    -- ----------------------------
    -- Table structure for `tb_attribute`
    -- ----------------------------
    DROP TABLE IF EXISTS `tb_attribute`;
    CREATE TABLE `tb_attribute` (
      `attribute_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '属性 id',
      `type_id` int(11) DEFAULT NULL COMMENT '种类id',
      `attribute_name` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '属性名',
      `attributetype_id` int(11) NOT NULL COMMENT '属性类型id',
      `index_id` int(5) DEFAULT NULL,
      PRIMARY KEY (`attribute_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;-- ----------------------------
    -- Records of tb_attribute
    -- ----------------------------
    INSERT INTO tb_attribute VALUES ('4', '1', '123', '1', '4');
    INSERT INTO tb_attribute VALUES ('5', '1', 'sss', '3', '2');
    INSERT INTO tb_attribute VALUES ('6', '1', '111', '2', '0');
    INSERT INTO tb_attribute VALUES ('7', '2', 'rere', '1', '0');
    INSERT INTO tb_attribute VALUES ('8', '2', '333', '4', '1');
    INSERT INTO tb_attribute VALUES ('9', '1', 'gadfalsdfas', '4', '1');
    INSERT INTO tb_attribute VALUES ('10', '1', 'dd', '2', '3');
    INSERT INTO tb_attribute VALUES ('11', '3', 'co', '1', '0');
    INSERT INTO tb_attribute VALUES ('12', '3', 'eee', '1', '1');
    INSERT INTO tb_attribute VALUES ('13', '3', 'ffffffff', '1', '2');
    INSERT INTO tb_attribute VALUES ('14', '3', 'ggggg', '1', '3');
    INSERT INTO tb_attribute VALUES ('15', '1', '234', '4', '5');
    INSERT INTO tb_attribute VALUES ('16', '1', '7556', '2', '6');
    INSERT INTO tb_attribute VALUES ('17', '1', '8', '2', '7');
    INSERT INTO tb_attribute VALUES ('18', '1', '98', '3', '8');
    INSERT INTO tb_attribute VALUES ('19', null, '1', '4', null);
    INSERT INTO tb_attribute VALUES ('20', null, '12', '4', null);
    INSERT INTO tb_attribute VALUES ('21', '4', 'fgdsf', '3', '0');
    INSERT INTO tb_attribute VALUES ('22', '5', 'a', '1', '0');
    INSERT INTO tb_attribute VALUES ('23', '5', 'b', '4', '1');
    INSERT INTO tb_attribute VALUES ('24', '5', 'c', '2', '2');
    INSERT INTO tb_attribute VALUES ('25', null, 'f', '1', null);
    INSERT INTO tb_attribute VALUES ('33', '6', 'a', '1', '0');
    INSERT INTO tb_attribute VALUES ('34', '6', 'b', '4', '1');
    INSERT INTO tb_attribute VALUES ('35', '6', 'c', '2', '2');
    INSERT INTO tb_attribute VALUES ('36', '6', 'jkl', '3', '3');
    INSERT INTO tb_attribute VALUES ('37', '1', 'dsa', '2', '9');
      

  10.   

    测试:
    CALL p_get_attribute_csv_data('SS');
    SELECT * FROM tb_temp_attribute_info; CALL p_get_attribute_csv_data('TT');
    SELECT * FROM tb_temp_attribute_info; 用你的代码没有问题,去掉SP的的SELECT * FROM tb_temp_attribute_info; 
      

  11.   

    应该是MYSQL中的一个BUG,对于临时表,在存储过程中MYSQL一直使用了它放置在缓存中的表结构。说明一下你的MYSQL版本。
      

  12.   

    用物理表测试一下,也是这样,估计在动态执行SQL语句后,执行SELECT * FROM 表名,取的还是上次
    的表
      

  13.   

    我的MySql版本是5.1.51,我也觉得是这问题!估计是只能转变方式解决这个问题了,谢谢楼上各位!