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

标签 sql mysql stored-procedures dynamic-sql

我正在玩 Peter Brawley 撰写的文章中的一些代码 found here在pdf的第6页。我试图弄清楚如何使它自动化,以便程序的结果自动放在选择查询中。现在我正在做的是调用过程,将结果导出到文本文件,手动转到文本文件(用鼠标单击),复制结果并将其粘贴到选择语句中。我一直无法弄清楚如何将 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 @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 | select DISTINCT CONCAT('Sum(if(pivotcol=",pivotcol",sumcol,0)) AS'pivotcol,'')..

最佳答案

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

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

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

来吧 mySQL 团队,我一直祈祷......

关于sql - 自动将调用过程的结果放入 select 语句中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3214929/

相关文章:

mysql - 创建 MySQL 存储过程时出现错误 1604。 MySQL 版本 5.7.19

MySQL UPDATE 语句因子查询而失败

php - mysql max 从 phpmyadmin 工作,但从 php 脚本给我一个错误的值?

MySQL 行号是-58684。怎么可能?

mysql - 与 MySQL FIND_IN_SET 相反

sql - SQL 存储过程中每个客户的求和和计算

python - 将图像插入 PostgresQL

sql - 如何显示相关(建议)关键字?

java - 回滚在 Java 中不起作用

mysql全文索引: why result of match against is not as good as result of like?