SQL代码如下:#建表,插数据
CREATE TABLE AA(iID int,sName varchar(50),iAge int)
INSERT INTO AA 
SELECT 1,'A',3 UNION 
SELECT 2,'A',2 UNION 
SELECT 3,'B',4 UNION 
SELECT 4,'B',8 UNION 
SELECT 5,'A',9 
#建表,插数据
CREATE TABLE AB(iID int,sSchool varchar(50),iMoney int,iTest int)
INSERT INTO AB 
SELECT 1,'清华',200,95 UNION
SELECT 2,'北大',220,85 UNION
SELECT 3,'清华',70,60 UNION
SELECT 4,'清华',20,50 UNION
SELECT 5,'北大',200,15 UNION
SELECT 6,'清华',65,90 #测试
SELECT sName,sum(iAge) as a
FROM AA
#INNER JOIN AB ON AA.iID=AB.iID 
#WHERE AB.sschool='北大'
GROUP by sNameDROP PROCEDURE TA
#建存储过程
CREATE PROCEDURE TA(vSchool varchar(50))
BEGIN
declare  A varchar(8000);
declare  B varchar(8000);
declare  C varchar(8000);
declare  D varchar(8000);SET A='SELECT sName,sum(iAge) 
              as a FROM AA ' ;
   SELECT A;
#判断参数是否有输入,如果没有,就不进行表关联,条件去掉此条件
IF LENGTH(vSchool) <> 0 THEN
   SET B='INNER JOIN AB ON AA.iID=AB.iID ';   
   SELECT B;
   set C=concat('WHERE AB.sschool= ','\'' ,vSchool,'\'') ;       
      SELECT C;
END IF;
    SET D=' GROUP by sName ';    
       SELECT D;
    SET @E=CONCAT(A,if(ISNULL(B),' ',B),if(ISNULL(C),' ',C),D);
PREPARE stmt1 FROM @E; 
    SELECT @E;   
    EXECUTE stmt1;            
    DEALLOCATE PREPARE stmt1; 
END#测试存储过程
CALL TA('')
CALL TA('清华')
CALL TA('北大')
select LENGTH('清华')
select LENGTH('')问题:
    1:测试例子里面,只有一个参数,一个表关联。。实际存储过程,有7,8个参数,4-5个关联表。按例子的写法,就显得太复杂了。。有没有什么另外的办法实现?
    2:此存储过程的目的:根据参数判断是否需要进行表关联,和查询条件的增减。实际应用是在数据的统计里。比如统计2009年北京市海淀区年龄超过30的人口数量,如果海淀区没有选择,那么就统计北京市年龄超过30的人口数量。出来的结果是固定的,条件是动态的。

解决方案 »

  1.   

    1、这种参数查询一般是用字符串累计生成SQL语句,再动态执行,基本没有简便方法;
    2、你可以试试将查询语句写完整(根据你要用到的表及参数),
    SQL语句会比较多,存入临时表中,再根据参数来判断使用哪条SQL语句,取记录内容,
    估计这种方法要简单一些。
      

  2.   

    测试了一下,因为你的参数比较多,又有若干组合(1-8个参数,任意抽取1-8个参数的组合,
    8取1、2-N个参数,结果非常多),看来用字符串累计生成SQL语句,再动态执行的方法是比较简单的
      

  3.   

    其实你自己都清楚处理逻辑了,只是想找人确认下罢啦
    像你这种表数、条件是不确定的,那可以像你那样,写一个存储过程接口,把相应参数传进去,然后在存储过程内部根据不同的条件来构造对应的SQL语句,但有个问题要注意的, 就是存放语句的变量,如你上面的“@E”,不能超出存储范围哦
      

  4.   


    你的意思是:
    如果有5个查询条件(A,B,C,D,E),
    那么当A为空时,有一条命令生成
    那么当B为空时,有一条命令生成


    那么当AB为空时,有一条命令生成
    那么当Ac为空时,有一条命令生成
    .....
    .....然后再根据参数,选择哪条命令,是吗??
      

  5.   


    处理逻辑是清楚。。
    但很长的SQL,一个个去拼接,挺麻烦的。。解决我的目的,还有没有其他的思路??
      

  6.   

    mysql> CALL TA('清华')//
    +--------------------------------------+
    | A                                    |
    +--------------------------------------+
    | SELECT sName,sum(iAge) as a FROM AA  |
    +--------------------------------------+
    1 row in set (0.00 sec)+---------------------------------+
    | B                               |
    +---------------------------------+
    | INNER JOIN AB ON AA.iID=AB.iID  |
    +---------------------------------+
    1 row in set (0.00 sec)+--------------------------+
    | C                        |
    +--------------------------+
    | WHERE AB.sschool= '清华' |
    +--------------------------+
    1 row in set (0.00 sec)+------------------+
    | D                |
    +------------------+
    |  GROUP by sName  |
    +------------------+
    1 row in set (0.00 sec)想了一下,基本没有什么其它的解决方法了。在MYSQL中只能按照你的这种方案。根据输入的参数 P1,P2,P3,P4...Pn 来逐个生成
    你的 @B部分 (inner join ...) 和 @C 部分where 
    另外一种或许简单一点儿的方法就是SQL语句改为如下格式mysql> SELECT sName,sum(iAge) as a
        -> FROM AA
        -> where iID in (select iID from ab where sSchool='北大')
        -> group by sName//
    +-------+------+
    | sName | a    |
    +-------+------+
    | A     |   11 |
    +-------+------+
    1 row in set (0.00 sec)mysql>
    你可以
    SELECT sName,sum(iAge) as a
    FROM AA
    where 1=1
    and iID in (select iID from ab where sSchool='北大')
    group by sName每次添加红字部分。
      

  7.   

    呵呵,没办法,查询是最难做的,各种语言、程序中都是一样,一个一个地判断,
    原来做过查询,在语言界面设置若干下拉框,下拉框内容固定,根据下拉框内容
    累加字符串生成SQL语句的WHERE,你的情况还要复杂一些,你还要根据内容
    决定使用什么表连接。
      

  8.   


    你这样的情况,我原来的存储过程就是这样的
    如果某个条件没有选择,那么原来就是aaa='' 这样处理,现在变成了aaa=''这个条件都不应该存在了。。所以麻烦了。
      

  9.   

    还是有点区别,
    1、表连接是确定的;
    2、只是要生成WHERE,
    比如选择dwdm,
    qw=""
    if 下拉框1<>''
    qw='dwdm='+下拉框1
    endif
    if 下拉框2<>''
    qw='dwdm='+下拉框2
    endifsql='select * from b1 inner join b2 on b1.id=b2.id where '+qw思路是一样的