场景:继上一个问题(使用存储过程中的游标循环mysql行)之后,我尝试执行一个嵌套的prepare语句,在该语句中,我向外部输入一个日期,然后调用内部语句,该语句从表中获取数据。
代码:
-- Create temporary table for the Output:
drop temporary table if exists `stats`;
create temporary table `stats`
(
col_name varchar(32) null,
num_nulls int null,
num_values int null
);
-- Procedure for the check:
drop procedure if exists `set_column_null_stats`;
delimiter $$
create procedure `set_column_null_stats`
(`p_col_name` varchar(128), `wanted_date` date)
begin
-- Set variables:
set @col_nme = `p_col_name`;
set @date1 = `wanted_date`;
prepare stmt from 'insert into `stats` (`col_name`) values (?);';
execute stmt using @col_nme;
deallocate prepare stmt;
-- count number of NULLS based on conditions:
set @sql_txt = concat(
'update `stats` s join(
select
count(1) as `nb`
from `btc`
where`btc`.`date` = ', @date1, ' and `btc`.`', @col_nme, '` is null)
t set `num_nulls` = t.`nb` where `col_name` = \'', @col_nme, '\';');
prepare stmt from @sql_txt;
execute stmt;
deallocate prepare stmt;
-- count number of not NULLS based on conditions:
set @sql_txt = concat(
'update `stats` s join(
select
count(1) as `nb`
from `btc`
where `btc`.`date` = ', @date1, ' and `btc`.`', @col_nme, '` is not null)
-- t set `num_values` = t.`nb` where `col_name` = \'', @col_nme, '\';');
set @sql_txt = concat('update `stats` s join (select count(1) as `nb` from `btc` where `', @col_nme, '` is not null) t set `num_values` = t.`nb` where `col_name` = \'', @col_nme, '\';');
prepare stmt from @sql_txt;
execute stmt;
deallocate prepare stmt;
end$$
delimiter ;
-- Procedure for looping through rows of `wanted_columns` table:
delimiter $$
drop procedure if exists `data_check_loop` $$
create procedure `data_check_loop`(`wanted_date` date)
begin
declare dateval date default null;
declare colval text default null;
-- boolean variable to indicate cursor is out of data
declare done tinyint default false;
-- declare a cursor to select the desired columns from the desired source table
declare cursor1
cursor for
select *
from `wanted_columns`;
-- catch exceptions
declare continue handler for not found set done = true;
set dateval = `wanted_date`;
-- open the cursor
open cursor1;
my_loop:
loop
fetch next from cursor1 into colval;
if done then
leave my_loop;
else
call `set_column_null_stats`(colval, dateval);
end if;
end loop;
close cursor1;
end $$
delimiter ;
-- Start the process with the wanted date:
call `data_check_loop`('2018-08-13');
select * from `stats`;
问题:此代码运行时没有错误,但不会给出任何结果。如果我只运行第一个准备好的语句,一个接一个地直接输入变量,就可以了。所以我猜问题出在我的第二个陈述上。
问:你知道我做错了什么吗?
obs:第二个代码应该循环一个表中的行(需要的列),并将它们一个接一个地提供给第一个语句(与日期一起,日期应该总是相同的)
obs2:我使用这个查询的目的是:从一个列为行的名称列表(“id1”,“date1”…)中,我打算读取每一行并将该值用在另一个表中,其中名称(“id1”,“date1”…)是列,并为我想要的每一列获取null值和notnull值的总和(同样,给定日期输入的另一个约束)。最后,对于每个原始行(表1),我将输出一个带有#null和#notnull的新行。
例如,表1:
Col_names
Id1
Name1
Date1
Process
Time
Class
例如,表2:
Id1 Name1 Date1 Process Time Class
aa test1 01/01 3 NULL A
NULL test2 01/02 4 NULL b
bb test3 NULL 3 NULL NULL
例如输出:
Col_name #Null #notNull
Id1 1 2
Name1 0 3
Date1 1 2
Process 0 3
Time 3 0
Class 1 2
1条答案
按热度按时间7xllpg7q1#
如果您想将列转换为记录,则需要在值所在的位置结束计数
null
或者not null
为了那个专栏。在大多数数据库系统中,将列转换为记录的过程称为unpivot,这一点受支持
UNPIVOT()
但是mysql不支持这一点。所以通常这是用
UNION
结合一些聚合函数,如MAX()
,MIX()
,SUM()
以及COUNT()
和一个CASE END
要模拟的子句UNPIVOT()
在mysql上。查询
结果
演示