自动将被调用过程的结果放入select语句中

时间:2010-07-09 17:07:29

标签: sql mysql stored-procedures dynamic-sql

我正在玩一些来自Peter Brawley found here在pdf第6页上写的文章中的代码。我试图弄清楚如何自动化它,以便程序的结果自动放在选择查询中。现在我正在做的是调用过程,将结果导出到文本文件中,手动转到文本文件(用鼠标点击),复制结果并将其粘贴到select语句中。我无法弄清楚如何将select语句插入到过程中,或者将过程放入我可以从select语句调用的数据库或变量中的表中。有什么想法吗?

以下是Peter Brawley的示例代码,我一直在努力实现自动化:

use database;
DROP PROCEDURE IF EXISTS writesumpivot;
DELIMITER |
CREATE PROCEDURE writesumpivot(
    db CHAR(64), tbl CHAR(64), pivotcol CHAR(64), sumcol CHAR(64)
)
BEGIN
DECLARE datadelim CHAR(1) DEFAULT '"';
DECLARE comma CHAR(1) DEFAULT ',';
DECLARE singlequote CHAR(1) DEFAULT CHAR(39);
SET @sqlmode = (SELECT @@sql_mode);
SET @@sql_mode='';
SET @pivotstr = CONCAT( 'SELECT DISTINCT CONCAT(', singlequote,
                    ',SUM(IF(', pivotcol, ' = ', datadelim, singlequote,
                    comma, pivotcol, comma, singlequote, datadelim,
                    comma, sumcol, ',0)) AS `',
                    singlequote, comma, pivotcol, comma, singlequote, '`',
                    singlequote, ') AS sumpivotarg FROM ', db, '.', tbl, 
                    ' WHERE ', pivotcol, ' IS NOT NULL' );
-- UNCOMMENT TO SEE THET MIDLEVEL SQL:
-- SELECT @pivotstr;
PREPARE stmt FROM @pivotstr;
EXECUTE stmt;
drop prepare stmt;
SET @@sql_mode=@sqlmode;
END
|
DELIMITER ;
call writesumpivot('database', 'table', 'pivotcol','sumcol');

然后Select语句如下:

SELECT
    infoField
    [results of the call]
FROM
    database.table
GROUP BY infoField;

假设我已经运行了调用,导出结果,复制它们并将它们粘贴到select语句中,我在SELECT查询中调用的个人结果将如下所示:

SELECT 
    infoField
    ,SUM(IF(pivotcol = "Yellow",sumcol,0)) AS `Yellow`
    ,SUM(IF(pivotcol = "Red",sumcol,0)) AS `Red`
    ,SUM(IF(pivotcol = "Purple",sumcol,0)) AS `Purple`
    ,SUM(IF(pivotcol = "Orange",sumcol,0)) AS `Orange`
    ,SUM(IF(pivotcol = "Green",sumcol,0)) AS `Green`
    ,SUM(IF(pivotcol = "Blue",sumcol,0)) AS `Blue`
    ,SUM(IF(pivotcol = "White",sumcol,0)) AS `White`
FROM database.table
GROUP BY infoField;

运行上面的select语句为我提供了我需要的数据透视表。我试着弄清楚如何将其纳入网站,这就是为什么它需要自动化。

我尝试插入一个create table,然后引用该表,但没有得到理想的结果。 编辑程序的最后一部分如下:

--SELECT @pivotstr;
DROP TABLE IF EXISTS temp2;
CREATE TABLE IF NOT EXISTS temp2(sumpivotarg varchar(8000));
PREPARE stmt FROM @pivotstr;  
...

更改了呼叫并选择如下:

call writesumpivot('database','table','pivotcol','sumcol');
insert into temp2(sumpivotarg) values(@pivotstr);

SELECT 
   table.infoField, temp2.sumpivotarg
FROM table, temp2
GROUP BY infoField

这样做的结果是通用代码,而不是对数据库中单元格内容进行求和。它看起来像这样:

  

infoField | sumpivotarg< - Col Headings

     

123 | SELECT DISTINCT CONCAT('Sum(if(pivotcol =“,pivotcol”,sumcol,0))AS 'pivotcol,'')..

     

124 | SELECT DISTINCT CONCAT('Sum(if(pivotcol =“,pivotcol”,sumcol,0))AS 'pivotcol,'')..

     

125 |选择DISTINCT CONCAT('Sum(if(pivotcol =“,pivotcol”,sumcol,0))AS 'pivotcol,'')..

2 个答案:

答案 0 :(得分:1)

我并不是说对mySQL有任何不尊重,但是整个写入临时表解决方案以便在存储过程之间传递表格数据是不理想和危险的(在现实世界的事务处理中)。我真的希望mySQL团队能够构建一些企业级存储过程功能。此外,mySQL函数无法返回表是一个明显的缺点。

我一直在慢慢地将过程从MSSQL转移到Linux和mySQL。程序和功能部门中mySQL的缺点是强制一些主要的kludgey类型重写(ala临时表和全局变量等)。

我已经写了大约20年的SP(SQL Server之前的Sybase),并且强烈地感到使用动态SQL并没有利用服务器端数据库。许多人尝试在客户端级别实现数据层,但服务器更适合此任务。它是功能和数据的自然分工。此外,对于相同的进程,同时在服务器上运行多个预编译调用比重复调用服务器更加优化。

加入mySQL团队,我的手指交叉......

答案 1 :(得分:0)

您可以在数据库中创建临时表。使用SQL insert将数据作为存储过程执行的结果插入临时表。之后,您可以在select语句中使用该临时表。

以下是一个答案,说明如何做到这一点:

Use result set of mysql stored procedure in another stored procedure

提到一个类似的问题:

MySQL How to INSERT INTO temp table FROM Stored Procedure