mysql存储过程示例
1 DROP PROCEDURE if exists p_report_xxsjtjb$$ 2 CREATE PROCEDURE p_report_xxsjtjb(IN pi_branchid INT(11), -- 分店id 3 IN pi_sb SMALLINT, -- 市别,0:午市;1:晚市;-1:全天 4 IN pi_ksrq DATETIME, -- 开始日期, 5 IN pi_jsrq DATETIME, -- 结束日期 6 IN pi_cxlx SMALLINT, -- 查询类型 1:应收金额 2:实收金额 3:结算人数 4:开台数 7 IN pi_qy VARCHAR(50), -- 餐台所属区域 -1:全部 非-1:区域id 8 OUT po_errmsg VARCHAR(100) 9 -- 错误信息 10 ) 11 SQL SECURITY INVOKER 12 COMMENT '详细数据统计表' 13 label_main: 14 BEGIN 15 -- 返回字段说明如下(2个固定字段+不固定字段): 16 -- 区域 桌号 时间列1 时间列2 时间列3..... 17 -- 18 -- 返回数据举例(返回值包含多条数据): 19 -- 大堂 1 22 33 44 20 21 22 DECLARE v_date_start DATETIME; 23 DECLARE v_date_end DATETIME; 24 DECLARE v_date_interval DATETIME; #时间间隔 25 DECLARE v_loop_num INT DEFAULT 0; #根据开始结束时间和显示类型,来设置循环次数 26 DECLARE v_table_index INT; 27 DECLARE v_table_id VARCHAR(50); 28 DECLARE v_sql VARCHAR(5000) DEFAULT ''; 29 30 -- 异常处理模块,出现异常返回null 31 DECLARE EXIT HANDLER FOR SQLEXCEPTION 32 BEGIN 33 SELECT NULL; 34 GET DIAGNOSTICS CONDITION 1 po_errmsg = MESSAGE_TEXT; 35 END; 36 37 IF pi_branchid IS NULL THEN 38 SELECT NULL; 39 SET po_errmsg = '分店ID输入不能为空'; 40 LEAVE label_main; 41 END IF; 42 43 44 SET @@max_heap_table_size = 1024 * 1024 * 300; 45 SET @@tmp_table_size = 1024 * 1024 * 300; 46 47 #设置循环次数,处理开始结算时间 48 SET v_date_start = str_to_date(concat(date_format(pi_ksrq, '%Y-%m-%d'), '00:00:00'), '%Y-%m-%d %H:%i:%s'); 49 SET v_date_end = str_to_date(concat(date_format(pi_jsrq, '%Y-%m-%d'), '23:59:59'), '%Y-%m-%d %H:%i:%s'); 50 SET v_date_interval = date_sub(date_add(v_date_start, INTERVAL 1 DAY), INTERVAL 1 SECOND); 51 SET v_loop_num = timestampdiff(DAY, v_date_start, v_date_end) + 1; 52 53 #创建订单临时内存表 54 DROP TEMPORARY TABLE IF EXISTS t_temp_order; 55 CREATE TEMPORARY TABLE t_temp_order 56 ( 57 orderid VARCHAR(50), 58 begintime DATETIME, 59 tableid VARCHAR(50), 60 womanNum INT, 61 childNum INT, 62 mannum INT 63 ) ENGINE = MEMORY DEFAULT CHARSET = utf8; 64 65 IF pi_sb > -1 THEN 66 INSERT INTO t_temp_order 67 SELECT orderid 68 , begintime 69 , currenttableid 70 , womanNum 71 , childNum 72 , mannum 73 FROM 74 t_order USE INDEX (IX_t_order_begintime) 75 WHERE 76 branchid = pi_branchid 77 AND begintime BETWEEN v_date_start AND v_date_end -- 需要创建索引IX_t_order_begintime 78 AND shiftid = pi_sb 79 AND orderstatus = 3; 80 ELSE 81 INSERT INTO t_temp_order 82 SELECT orderid 83 , begintime 84 , currenttableid 85 , womanNum 86 , childNum 87 , mannum 88 FROM 89 t_order USE INDEX (IX_t_order_begintime) 90 WHERE 91 branchid = pi_branchid 92 AND begintime BETWEEN v_date_start AND v_date_end -- 需要创建索引IX_t_order_begintime 93 AND orderstatus = 3; 94 END IF; 95 96 #为订单内存表创建索引 97 CREATE UNIQUE INDEX ix_t_temp_order_orderid ON t_temp_order (orderid); 98 99 100 IF pi_cxlx = 1 THEN 101 DROP TEMPORARY TABLE IF EXISTS t_temp_order_detail; 102 CREATE TEMPORARY TABLE t_temp_order_detail 103 ( 104 orderid VARCHAR(50), 105 dishnum DOUBLE(13, 2), 106 orignalprice DOUBLE(13, 2), 107 tableid VARCHAR(50), 108 begintime DATETIME, 109 childdishtype TINYINT, 110 primarykey VARCHAR(50), 111 superkey VARCHAR(50) 112 ) ENGINE = MEMORY DEFAULT CHARSET = utf8 MAX_ROWS = 1000000; 113 114 # 向临时订单详情内存表中放值 115 INSERT INTO t_temp_order_detail 116 SELECT b.orderid 117 , b.dishnum 118 , b.orignalprice 119 , a.tableid 120 , a.begintime 121 , b.childdishtype 122 , b.primarykey 123 , b.superkey 124 FROM 125 t_temp_order a, t_order_detail b 126 WHERE 127 a.orderid = b.orderid 128 AND b.orignalprice > 0; 129 130 # 删除套餐明细 131 DROP TEMPORARY TABLE IF EXISTS t_temp_keys; 132 CREATE TEMPORARY TABLE t_temp_keys 133 ( 134 primarykey VARCHAR(50) 135 ) ENGINE = MEMORY DEFAULT CHARSET = utf8 MAX_ROWS = 1000000; 136 INSERT INTO t_temp_keys 137 SELECT primarykey 138 FROM 139 t_temp_order_detail 140 WHERE 141 childdishtype = 2; 142 143 DELETE 144 FROM 145 t_temp_order_detail 146 USING 147 t_temp_order_detail, t_temp_keys 148 WHERE 149 t_temp_order_detail.superkey = t_temp_keys.primarykey 150 AND t_temp_order_detail.primarykey != t_temp_keys.primarykey; 151 152 CREATE INDEX ix_t_temp_order_detail_begintime ON t_temp_order_detail (begintime); 153 154 #创建结算明细内存表 155 ELSEIF pi_cxlx = 2 THEN 156 DROP TEMPORARY TABLE IF EXISTS t_temp_settlement_detail; 157 CREATE TEMPORARY TABLE t_temp_settlement_detail 158 ( 159 orderid VARCHAR(50), 160 payway INT, 161 payamount DOUBLE(13, 2), 162 begintime DATETIME, 163 tableid VARCHAR(50) 164 ) ENGINE = MEMORY DEFAULT CHARSET = utf8 MAX_ROWS = 1000000; 165 166 #生产临时结算明细表数据 167 INSERT INTO t_temp_settlement_detail 168 SELECT b.orderid 169 , b.payway 170 , b.payamount 171 , a.begintime 172 , a.tableid 173 FROM 174 t_temp_order a, t_settlement_detail b 175 WHERE 176 a.orderid = b.orderid 177 AND b.payway IN (0, 1, 5, 8, 13, 17, 18) -- shangwenchao 2015/12/21 22:46:49 增加结算方式13, 17 ,18 178 AND b.payamount > 0; 179 180 CREATE INDEX ix_t_temp_settlement_detail_begintime ON t_temp_settlement_detail (begintime); 181 182 #创建会员消费内存表 183 DROP TEMPORARY TABLE IF EXISTS t_temp_order_member; 184 CREATE TEMPORARY TABLE t_temp_order_member 185 ( 186 orderid VARCHAR(50), 187 Inflated DOUBLE(13, 2), 188 begintime DATETIME, 189 tableid VARCHAR(50) 190 ) ENGINE = MEMORY DEFAULT CHARSET = utf8 MAX_ROWS = 1000000; 191 192 #生成临时会员结算数据 193 INSERT INTO t_temp_order_member 194 SELECT b.orderid 195 , b.Inflated 196 , a.begintime 197 , a.tableid 198 FROM 199 t_temp_order a, t_order_member b 200 WHERE 201 a.orderid = b.orderid; 202 CREATE INDEX ix_t_temp_order_member_begintime ON t_temp_order_member (begintime); 203 END IF; 204 205 206 #筛选桌子 207 DROP TEMPORARY TABLE IF EXISTS t_temp_table; 208 CREATE TEMPORARY TABLE t_temp_table 209 ( 210 areaname VARCHAR(10), 211 tableid VARCHAR(50), 212 tableNo VARCHAR(50) 213 ) ENGINE = MEMORY DEFAULT CHARSET = utf8; 214 215 IF pi_qy = '-1' THEN 216 INSERT INTO t_temp_table (areaname, tableid, tableNo) 217 SELECT b.areaname 218 , a.tableid 219 , a.tableNo 220 FROM 221 t_table a, t_tablearea b 222 WHERE 223 a.areaid = b.areaid 224 AND b.branchid = pi_branchid; 225 ELSE 226 INSERT INTO t_temp_table (areaname, tableid, tableNo) 227 SELECT b.areaname 228 , a.tableid 229 , a.tableNo 230 FROM 231 t_table a, t_tablearea b 232 WHERE 233 a.areaid = b.areaid 234 AND b.areaid = pi_qy 235 AND b.branchid = pi_branchid; 236 END IF; 237 238 239 #创建结果集 240 DROP TEMPORARY TABLE IF EXISTS t_temp_res; 241 CREATE TEMPORARY TABLE t_temp_res 242 ( 243 areaname VARCHAR(10), 244 tableid VARCHAR(50), 245 stime VARCHAR(10), 246 svalue DOUBLE(13, 2) 247 ) ENGINE = MEMORY DEFAULT CHARSET = utf8; 248 249 250 #创建虚增结果集 251 DROP TEMPORARY TABLE IF EXISTS t_temp_inflated; 252 CREATE TEMPORARY TABLE t_temp_inflated 253 ( 254 tableid VARCHAR(50), 255 stime VARCHAR(10), 256 svalue DOUBLE(13, 2) 257 ) ENGINE = MEMORY DEFAULT CHARSET = utf8; 258 259 #####################################遍历桌子及统计天数,生成结果数据########################################## 260 WHILE v_loop_num > 0 261 DO 262 263 #统计应收 264 IF pi_cxlx = 1 THEN 265 INSERT INTO t_temp_res (tableid, stime, svalue) 266 SELECT tableid 267 , date_format(v_date_start, '%Y/%m/%d') 268 , sum(dishnum * orignalprice) 269 FROM 270 t_temp_order_detail 271 WHERE 272 begintime BETWEEN v_date_start AND v_date_interval 273 GROUP BY 274 tableid; 275 276 #统计实收 277 ELSEIF pi_cxlx = 2 THEN 278 INSERT INTO t_temp_res (tableid, stime, svalue) 279 SELECT tableid 280 , date_format(v_date_start, '%Y/%m/%d') 281 , ifnull(sum(payamount), 0) 282 FROM 283 t_temp_settlement_detail 284 WHERE 285 begintime BETWEEN v_date_start AND v_date_interval 286 GROUP BY 287 tableid; 288 289 INSERT INTO t_temp_inflated 290 SELECT tableid 291 , date_format(v_date_start, '%Y/%m/%d') 292 , ifnull(sum(Inflated), 0) 293 FROM 294 t_temp_order_member 295 WHERE 296 begintime BETWEEN v_date_start AND v_date_interval 297 GROUP BY 298 tableid; 299 300 #INSERT INTO t_temp_res (tableid, stime, svalue) VALUES (v_table_id, date_format(v_date_start, '%Y/%m/%d'), @shishou - @xuzeng); 301 302 #统计结账人数 303 ELSEIF pi_cxlx = 3 THEN 304 INSERT INTO t_temp_res (tableid, stime, svalue) 305 SELECT tableid 306 , date_format(v_date_start, '%Y/%m/%d') 307 , ifnull(sum(mannum + womanNum + childNum), 0) 308 FROM 309 t_temp_order 310 WHERE 311 begintime BETWEEN v_date_start AND v_date_interval 312 GROUP BY 313 tableid; 314 315 #统计开台数据 316 ELSEIF pi_cxlx = 4 THEN 317 INSERT INTO t_temp_res (tableid, stime, svalue) 318 SELECT tableid 319 , date_format(v_date_start, '%Y/%m/%d') 320 , count(1) 321 FROM 322 t_temp_order 323 WHERE 324 begintime BETWEEN v_date_start AND v_date_interval 325 GROUP BY 326 tableid; 327 #退出程序 328 ELSE 329 SELECT NULL; 330 SET po_errmsg = '显示类型输入有误 1:应收金额 2:实收金额 3:结算人数 4:开台数'; 331 LEAVE label_main; 332 END IF; 333 334 #动态拼装sql,为后面的返回数据做准备 335 SET @date_start = date_format(v_date_start, '%Y/%m/%d'); 336 SET v_sql = concat(v_sql, ',max(case stime when \'', @date_start, '\' then svalue else 0 end) \'', @date_start, '\''); 337 338 SET v_date_start = date_add(v_date_start, INTERVAL 1 DAY); 339 SET v_date_interval = date_add(v_date_interval, INTERVAL 1 DAY); 340 SET v_loop_num = v_loop_num - 1; 341 END WHILE; 342 343 344 #删除不需要统计的桌号 345 DELETE t_temp_res 346 FROM 347 t_temp_res 348 LEFT JOIN t_temp_table 349 ON t_temp_res.tableid = t_temp_table.tableid 350 WHERE 351 t_temp_table.tableid IS NULL; 352 353 #更新实收数据 354 UPDATE t_temp_res a, t_temp_inflated b 355 SET 356 a.svalue = a.svalue - b.svalue 357 WHERE 358 a.tableid = b.tableid 359 AND a.stime = b.stime; 360 361 #更新桌号及区域名称 362 UPDATE t_temp_res a, t_temp_table b 363 SET 364 a.areaname = b.areaname, a.tableid = b.tableNo 365 WHERE 366 a.tableid = b.tableid; 367 368 #返回数据 369 SET v_sql = concat('SELECT areaname, tableid', v_sql); 370 SET v_sql = concat(v_sql, ' FROM t_temp_res GROUP BY areaname, tableid order by tableid-0,areaname'); 371 SET @sql_xxsj = v_sql; 372 PREPARE s1 FROM @sql_xxsj; 373 EXECUTE s1; 374 DEALLOCATE PREPARE s1; 375 376 #清空内存表 377 -- DROP TEMPORARY TABLE IF EXISTS t_temp_order; 378 -- DROP TEMPORARY TABLE IF EXISTS t_temp_order_detail; 379 -- DROP TEMPORARY TABLE IF EXISTS t_temp_settlement_detail; 380 -- DROP TEMPORARY TABLE IF EXISTS t_temp_order_member; 381 -- DROP TEMPORARY TABLE IF EXISTS t_temp_table; 382 -- DROP TEMPORARY TABLE IF EXISTS t_temp_res; 383 -- DROP TEMPORARY TABLE IF EXISTS t_temp_inflated; 384 -- DROP TEMPORARY TABLE IF EXISTS t_temp_keys; 385 END 386 $$
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)