用户统计日月报表 PROC_STAT_MONTHUSERCOUNT

本文介绍了一个用于统计每月及每日用户数据的过程,包括删除旧数据、插入新数据,并通过各种条件筛选来统计总用户数、新增用户数、付费用户数等关键指标。
CREATE OR REPLACE PROCEDURE "PROC_STAT_MONTHUSERCOUNT"
as
begin
delete from tbl_stat_month_usercount where stuc_datatime=trunc(sysdate-1,'MM');
delete from tbl_stat_daily_usercount where dauc_datatime=trunc(sysdate-1);
--各业务用户
[@more@]insert all
into tbl_stat_month_usercount values (trunc(sysdate-1,'MM'),usse_busiid_fk,总用户,当月新增用户数,付费总用户,当月新增付费用户,卸载总用户,当月新增卸载用户,总沉默用户,0,Vip总用户,当月新增Vip用户,0,0,0,0,0,0,0,0,0,0)
into tbl_stat_daily_usercount values (trunc(sysdate-1),usse_busiid_fk,总用户,前一天新增用户数,付费总用户,0,前一天新增付费用户,卸载总用户,前一天新增卸载用户,总沉默用户,0,Vip总用户,前一天新增Vip用户,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
select usse_busiid_fk,count(*) 总用户,count( case when us.usse_activatedate>=trunc(sysdate-1,'MM') then 1 end ) 当月新增用户数,count( case when us.usse_activatedate>=trunc(sysdate-1) then 1 end ) 前一天新增用户数, count(fee.smre_uid_fk) 付费总用户,count( case when fee.smre_date>=trunc(sysdate-1,'MM') then fee.smre_uid_fk end ) 当月新增付费用户,count( case when fee.smre_date>=trunc(sysdate-1) then fee.smre_uid_fk end ) 前一天新增付费用户, count(dect.deac_uid_fk) 卸载总用户,count( case when dect.deac_date>=trunc(sysdate-1,'MM') then dect.deac_uid_fk end ) 当月新增卸载用户,count( case when dect.deac_date>=trunc(sysdate-1) then dect.deac_uid_fk end ) 前一天新增卸载用户, 0 总沉默用户,0 当月新增沉默用户,0 前一天新增沉默用户, count(vip.vip_uid) Vip总用户,count( case when us.createdate>=trunc(sysdate-1,'MM') then vip.vip_uid end ) 当月新增Vip用户,count( case when us.usse_activatedate>=trunc(sysdate-1) then vip.vip_uid_fk end ) 前一天新增Vip用户 ,0,0,0,0,0,0
from
... commit;
execute immediate 'truncate table tbl_temp_dailyusercount';
insert into tbl_temp_dailyusercount
select trunc(sysdate-1) stuc_datatime, bi.busi_id stuc_bussiid_fk ,q.totalcarduser,q.newcarduser,q.newdailycarduser, --c.totalsilenceuser,c.newsilenceuser,newdailysilenceuser, wapm.totalwappaymonthuser,wapm.newwappaymonthuser,wapm.newdailywappaymonthuser, b.totalpaymonthuser,b.newpaymonthuser,b.newdailypaymonthuser, a.totalsmsrechargeuser,a.newsmsrechargeuser,a.newdailysmsrechargeuser, wa.totalwaprechargeuser,wa.newwaprechargeuser,wa.newdailywaprechargeuser from
... commit;
merge into tbl_stat_daily_usercount dauc
using (select trunc(sysdate-1) datatime,us.usse_busiid_fk,count( fee.smre_uid_fk ) 新增且付费,
count(q.qcpm_his_uid_fk) 新增且付费点卡,count(sm.smre_uid_fk) 新增且付费充值,count(smch.smpc_uid_fk) 新增且付费包月 ,count(wapmh.wamo_his_uid_fk) 新增且Wap包月,count(wa.ware_uid_fk) 新增且Wap充值
... commit;
update tbl_stat_daily_usercount dauc set (dauc.dauc_feedailynewusercount,dauc.dauc_carddailynewusercount,
dauc.dauc_smsrechdailynewusercount,dauc.dauc_smspmdailynewusercount,dauc_waprechdailynewusercount,dauc_wappmdailynewusercount) =
(select count( fee.smre_uid_fk ) 新增且付费, count(q.qcpm_his_uid_fk) 新增且付费点卡,count(sm.smre_uid_fk) 新增且付费充值,count(smch.smpc_uid_fk) 新增且付费包月 ,count(wapmh.wamo_his_uid_fk) 新增且Wap包月,count(wa.ware_uid_fk) 新增且Wap充值

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9614263/viewspace-1007526/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9614263/viewspace-1007526/

本 PPT 介绍了制药厂房中供配电系统的总体概念与设计要点,内容包括: 洁净厂房的特点及其对供配电系统的特殊要求; 供配电设计的一般原则与依据的国家/行业标准; 从上级电网到工厂变电所、终端配电的总体结构与模块化设计思路; 供配电范围:动力配电、照明、通讯、接地、防雷与消防等; 动力配电中电压等级、接地系统形式(如 TN-S)、负荷等级与可靠性、UPS 配置等; 照明的电源方式、光源选择、安装方式、应急与备用照明要求; 通讯系统、监控系统在生产管理与消防中的作用; 接地与等电位连接、防雷等级与防雷措施; 消防设施及其专用供电(消防泵、排烟风机、消防控制室、应急照明等); 常见高压柜、动力柜、照明箱等配电设备案例及部分设计图纸示意; 公司已完成的典型项目案例。 1. 工程背景与总体框架 所属领域:制药厂房工程的公用工程系统,其中本 PPT 聚焦于供配电系统。 放在整个公用工程中的位置:与给排水、纯化水/注射用水、气体与热力、暖通空调、自动化控制等系统并列。 2. Part 01 供配电概述 2.1 洁净厂房的特点 空间密闭,结构复杂、走向曲折; 单相设备、仪器种类多,工艺设备昂贵、精密; 装修材料与工艺材料种类多,对尘埃、静电等更敏感。 这些特点决定了:供配电系统要安全可靠、减少积尘、便于清洁和维护。 2.2 供配电总则 供配电设计应满足: 可靠、经济、适用; 保障人身与财产安全; 便于安装与维护; 采用技术先进的设备与方案。 2.3 设计依据与规范 引用了大量俄语标准(ГОСТ、СНиП、SanPiN 等)以及国家、行业和地方规范,作为设计的法规基础文件,包括: 电气设备、接线、接地、电气安全; 建筑物电气装置、照明标准; 卫生与安全相关规范等。 3. Part 02 供配电总览 从电源系统整体结构进行总览: 上级:地方电网; 工厂变电所(10kV 配电装置、变压
改动后编译继续报错,请解决: felix@W0600144-test2:/mydisk/ping_stat$ make make -C /lib/modules/4.15.0-213-generic/build M=/mydisk/ping_stat EXTRA_CFLAGS="-fno-pic" modules make[1]: Entering directory '/usr/src/linux-headers-4.15.0-213-generic' ./scripts/gcc-goto.sh: line 6: cannot create temp file for here-document: No space left on device CC [M] /mydisk/ping_stat/ping_stat.o /mydisk/ping_stat/ping_stat.c: In function ‘ping_stat_show’: /mydisk/ping_stat/ping_stat.c:118:50: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=] snprintf(time_buf, sizeof(time_buf), "%04d-%02d-%02d %02d:%02d:%02d", ~~~^ %04ld tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ~~~~~~~~~~~~~~~~~ /mydisk/ping_stat/ping_stat.c: At top level: /mydisk/ping_stat/ping_stat.c:138:21: error: variable ‘ping_stat_fops’ has initializer but incomplete type static const struct proc_ops ping_stat_fops = { ^~~~~~~~ /mydisk/ping_stat/ping_stat.c:139:6: error: ‘const struct proc_ops’ has no member named ‘proc_open’ .proc_open = ping_stat_open, // 打开时调用 ^~~~~~~~~ /mydisk/ping_stat/ping_stat.c:139:18: warning: excess elements in struct initializer .proc_open = ping_stat_open, // 打开时调用 ^~~~~~~~~~~~~~ /mydisk/ping_stat/ping_stat.c:139:18: note: (near initialization for ‘ping_stat_fops’) /mydisk/ping_stat/ping_stat.c:140:6: error: ‘const struct proc_ops’ has no member named ‘proc_read’ .proc_read = seq_read, // 读操作 ^~~~~~~~~ /mydisk/ping_stat/ping_stat.c:140:18: warning: excess elements in struct initializer .proc_read = seq_read, // 读操作 ^~~~~~~~ /mydisk/ping_stat/ping_stat.c:140:18: note: (near initialization for ‘ping_stat_fops’) /mydisk/ping_stat/ping_stat.c:141:6: error: ‘const struct proc_ops’ has no member named ‘proc_lseek’ .proc_lseek = seq_lseek, ^~~~~~~~~~ /mydisk/ping_stat/ping_stat.c:141:19: warning: excess elements in struct initializer .proc_lseek = seq_lseek, ^~~~~~~~~ /mydisk/ping_stat/ping_stat.c:141:19: note: (near initialization for ‘ping_stat_fops’) /mydisk/ping_stat/ping_stat.c:142:6: error: ‘const struct proc_ops’ has no member named ‘proc_release’ .proc_release = single_release, ^~~~~~~~~~~~ /mydisk/ping_stat/ping_stat.c:142:21: warning: excess elements in struct initializer .proc_release = single_release, ^~~~~~~~~~~~~~ /mydisk/ping_stat/ping_stat.c:142:21: note: (near initialization for ‘ping_stat_fops’) /mydisk/ping_stat/ping_stat.c: In function ‘ping_stat_init’: /mydisk/ping_stat/ping_stat.c:162:44: warning: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Wincompatible-pointer-types] if (!proc_create("ping_stat", 0, NULL, &ping_stat_fops)) { ^ In file included from /mydisk/ping_stat/ping_stat.c:8:0: ./include/linux/proc_fs.h:32:24: note: expected ‘const struct file_operations *’ but argument is of type ‘const struct proc_ops *’ struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops); ^~~~~~~~~~~ /mydisk/ping_stat/ping_stat.c: At top level: /mydisk/ping_stat/ping_stat.c:138:30: error: storage size of ‘ping_stat_fops’ isn’t known static const struct proc_ops ping_stat_fops = { ^~~~~~~~~~~~~~ scripts/Makefile.build:340: recipe for target '/mydisk/ping_stat/ping_stat.o' failed make[2]: *** [/mydisk/ping_stat/ping_stat.o] Error 1 Makefile:1596: recipe for target '_module_/mydisk/ping_stat' failed make[1]: *** [_module_/mydisk/ping_stat] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-4.15.0-213-generic' Makefile:12: recipe for target 'all' failed make: *** [all] Error 2
08-19
<think>我们遇到了多个编译错误,需要逐一解决。错误信息主要分为两类: 1. 关于时间格式化的警告(可以暂时忽略,但最好修复) 2. 关于`proc_ops`结构体的错误(这是主要问题) 具体错误分析及解决方案如下: ### 错误1:时间格式化警告 ```text /mydisk/ping_stat/ping_stat.c:118:50: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=] snprintf(time_buf, sizeof(time_buf), "%04d-%02d-%02d %02d:%02d:%02d", ~~~^ %04ld tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ~~~~~~~~~~~~~~~~~ ``` **原因**:`tm.tm_year`是`long int`类型,而格式字符串中使用了`%d`(用于`int`)。在64位系统上,`time_t`相关类型可能是长整型。 **修复方法**:将`%d`改为`%ld`,或者使用`%04d`并强制转换为`int`。但注意,`tm.tm_year`本身是`int`类型(根据标准),所以这里可能是由于`time_t`是64位导致的问题。实际上,`struct tm`的成员是`int`类型,所以这里可能是编译器误报。但为了消除警告,可以显式转换为`int`。 修改代码: ```c snprintf(time_buf, sizeof(time_buf), "%04d-%02d-%02d %02d:%02d:%02d", (int)tm.tm_year + 1900, (int)tm.tm_mon + 1, (int)tm.tm_mday, (int)tm.tm_hour, (int)tm.tm_min, (int)tm.tm_sec); ``` ### 错误2:`proc_ops`结构体相关错误(主要问题) ```text /mydisk/ping_stat/ping_stat.c:138:21: error: variable ‘ping_stat_fops’ has initializer but incomplete type static const struct proc_ops ping_stat_fops = { ^~~~~~~~ /mydisk/ping_stat/ping_stat.c:139:6: error: ‘const struct proc_ops’ has no member named ‘proc_open’ .proc_open = ping_stat_open, // 打开时调用 ^~~~~~~~~ ... ``` **原因分析**: - 错误信息显示`struct proc_ops`是不完整类型,且没有名为`proc_open`的成员。 - 这是因为在较旧的内核版本(如4.15)中,`proc_ops`结构体可能不存在。在旧内核中,`/proc`文件系统操作使用的是`struct file_operations`。 **历史背景**: - 在Linux 5.6之前,`/proc`文件系统使用`struct file_operations`。 - 从Linux 5.6开始,引入了`struct proc_ops`以提供更专门的操作,并逐步淘汰`file_operations`。 **解决方案**: 由于用户的内核版本是4.15,我们需要使用旧的`file_operations`结构体。 修改步骤: 1. **将`struct proc_ops`替换为`struct file_operations`** 2. **成员名称调整**: - `proc_open` -> `open` - `proc_read` -> `read` - `proc_lseek` -> `llseek` - `proc_release` -> `release` 修改后: ```c static const struct file_operations ping_stat_fops = { .open = ping_stat_open, // 打开时调用 .read = seq_read, // 读操作 .llseek = seq_lseek, // 定位 .release = single_release, // 释放 }; ``` 3. **修改`proc_create`函数调用**: 原代码: ```c proc_create("ping_stat", 0, NULL, &ping_stat_fops); ``` 在旧内核中,`proc_create`的第四个参数是`const struct file_operations *`,所以直接传递`&ping_stat_fops`即可。 4. **调整`ping_stat_open`函数**: 在`file_operations`中,`open`函数的原型为: ```c int (*open)(struct inode *, struct file *); ``` 而原来的`ping_stat_open`函数应该是匹配`proc_ops`的`proc_open`成员,其原型在旧内核中与`file_operations`的`open`一致。所以通常不需要修改函数实现,但需要检查函数定义。 检查`ping_stat_open`函数定义: ```c static int ping_stat_open(struct inode *inode, struct file *file) { return single_open(file, ping_stat_show, NULL); } ``` 这个定义是兼容旧内核的。 ### 错误3:`proc_create`参数类型不匹配 ```text /mydisk/ping_stat/ping_stat.c:162:44: warning: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Wincompatible-pointer-types] if (!proc_create("ping_stat", 0, NULL, &ping_stat_fops)) { ^ In file included from /mydisk/ping_stat/ping_stat.c:8:0: ./include/linux/proc_fs.h:32:24: note: expected ‘const struct file_operations *’ but argument is of type ‘const struct proc_ops *’ struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops); ^~~~~~~~~~~ ``` 这个错误是因为我们之前定义了`proc_ops`,但现在我们已经改为`file_operations`,所以这个警告应该消失。 ### 完整修改示例 修改后的`ping_stat.c`相关部分: ```c // ... 其他头文件 ... // 删除对proc_ops的依赖,使用file_operations static int ping_stat_open(struct inode *inode, struct file *file) { return single_open(file, ping_stat_show, NULL); } // 将proc_ops改为file_operations static const struct file_operations ping_stat_fops = { .open = ping_stat_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; // 在初始化函数中使用 static int __init ping_stat_init(void) { // ... 其他代码 ... if (!proc_create("ping_stat", 0, NULL, &ping_stat_fops)) { printk(KERN_ERR "Failed to create /proc/ping_stat\n"); nf_unregister_net_hook(&init_net, &nfho); return -ENOMEM; } // ... } ``` ### 额外建议 1. **内核版本兼容**:在代码中通过宏判断内核版本,以同时支持新旧内核。 例如: ```c #include <linux/version.h> ... #if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0) // 使用file_operations static const struct file_operations ping_stat_fops = { .open = ping_stat_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; #else // 使用proc_ops static const struct proc_ops ping_stat_fops = { .proc_open = ping_stat_open, .proc_read = seq_read, .proc_lseek = seq_lseek, .proc_release = single_release, }; #endif ``` 2. **修复时间格式化警告**:按照前面所述进行类型转换。 ### 重新编译 完成上述修改后,重新运行`make`命令。 §§相关问题§§ 1. 在内核开发中,如何编写跨多个内核版本的兼容性代码? 2. 除了`proc_ops`,还有哪些内核API在版本升级后发生了重大变化? 3. 如何在内核模块中安全地处理时间戳以避免2038年问题? 4. 为什么Linux内核要引入`proc_ops`替代`file_operations`用于proc文件系统? 5. 当内核模块编译出现类型不匹配警告时,应该如何处理?</think>### 编译错误分析与解决方案 根据错误信息,主要存在三个核心问题需要解决: #### 1. 临时文件创建失败(空间不足) ```bash ./scripts/gcc-goto.sh: line 6: cannot create temp file for here-document: No space left on device ``` **原因**:磁盘空间不足导致编译器无法创建临时文件 **解决方案**: ```bash # 检查磁盘空间 df -h /mydisk # 清理空间(选择合适操作) sudo apt clean # 清理包缓存 sudo journalctl --vacuum-size=200M # 清理日志 rm -rf ~/.cache/* # 清理用户缓存 ``` #### 2. 时间格式化警告(类型不匹配) ```c warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ ``` **修复方法**:修改时间格式化代码 ```c // 原始代码 snprintf(time_buf, sizeof(time_buf), "%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); // 修改为(使用%ld格式符) snprintf(time_buf, sizeof(time_buf), "%04ld-%02ld-%02ld %02ld:%02ld:%02ld", (long)tm.tm_year + 1900, (long)tm.tm_mon + 1, (long)tm.tm_mday, (long)tm.tm_hour, (long)tm.tm_min, (long)tm.tm_sec); ``` #### 3. proc_ops 兼容性问题(主要错误) ```c error: variable ‘ping_stat_fops’ has initializer but incomplete type ``` **原因分析**: - 内核版本4.15.0-213 使用旧的 `file_operations` 而非新的 `proc_ops` - `proc_ops` 结构在 Linux 5.6+ 才引入([内核提交记录](https://github.com/torvalds/linux/commit/97a32539b956)) **解决方案**: 修改代码使用兼容旧内核的 `file_operations`: ```c // 替换 proc_ops 为 file_operations static const struct file_operations ping_stat_fops = { .owner = THIS_MODULE, .open = ping_stat_open, // 对应 proc_open .read = seq_read, // 对应 proc_read .llseek = seq_lseek, // 对应 proc_lseek .release = single_release, // 对应 proc_release }; ``` 同时修改初始化函数: ```c // 修改 proc_create 调用 proc_create("ping_stat", 0, NULL, &ping_stat_fops); ``` ### 完整修复步骤 1. **释放磁盘空间**(关键前置步骤) ```bash sudo apt clean sudo rm -rf /var/log/*.gz ``` 2. **修改源码文件 `ping_stat.c`**: ```diff - static const struct proc_ops ping_stat_fops = { - .proc_open = ping_stat_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, - }; + static const struct file_operations ping_stat_fops = { + .owner = THIS_MODULE, + .open = ping_stat_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }; ``` 3. **修复时间格式化**: ```diff - snprintf(time_buf, sizeof(time_buf), "%04d-%02d-%02d %02d:%02d:%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); + snprintf(time_buf, sizeof(time_buf), "%04ld-%02ld-%02ld %02ld:%02ld:%02ld", + (long)tm.tm_year + 1900, (long)tm.tm_mon + 1, (long)tm.tm_mday, + (long)tm.tm_hour, (long)tm.tm_min, (long)tm.tm_sec); ``` 4. **重新编译**: ```bash make clean make ``` ### 兼容性增强建议 添加内核版本检测宏,使代码兼容新旧内核: ```c #include <linux/version.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) // 使用 proc_ops (Linux 5.6+) static const struct proc_ops ping_stat_fops = { .proc_open = ping_stat_open, .proc_read = seq_read, .proc_lseek = seq_lseek, .proc_release = single_release, }; #else // 使用 file_operations (旧内核) static const struct file_operations ping_stat_fops = { .owner = THIS_MODULE, .open = ping_stat_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; #endif ``` ### 验证编译 成功编译后应生成 `ping_stat.ko` 文件,可通过以下命令验证: ```bash # 检查模块依赖 modinfo ping_stat.ko # 测试加载 sudo insmod ping_stat.ko n=128 # 查看输出 cat /proc/ping_stat ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值