ON_EVENT 报错

错误提示:

error C2440: 'initializing' : cannot convert from 'const wchar_t [1]' to 'UINT'

error C2440: 'initializing' : cannot convert from 'AFX_PMSG' to 'UINT_PTR'

error C2078: too many initializers

错误原因:

放在了

BEGIN_MESSAGE_MAP(CCSDIDemoView, CView)
...
END_MESSAGE_MAP()

正确的应该放在:

BEGIN_EVENTSINK_MAP(CSDMSCom1View, CView)
//{{AFX_EVENTSINK_MAP(CAboutDlg)
ON_EVENT(CSDMSCom1View, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

在头文件中在函数事件响应函数前面加上
DECLARE_EVENTSINK_MAP()

转载于:https://www.cnblogs.com/vcerror/p/4289099.html

<think>我们正在处理一个SQL问题:在添加带有默认值的DATETIME类型列时遇到错误。具体SQL语句是:ADDCOLUMNregistration_datetimeDATETIMENOTNULLDEFAULTCURRENT_TIMESTAMP根据引用[1]中的示例,他们创建表时使用了`TIMESTAMPDEFAULTCURRENT_TIMESTAMP`,而这里我们试图在`DATETIME`类型上使用`DEFAULTCURRENT_TIMESTAMP`,这可能是问题所在。在MySQL中,`TIMESTAMP`和`DATETIME`类型在处理默认值上有所不同:-`TIMESTAMP`类型可以设置默认值为`CURRENT_TIMESTAMP`,并且还可以自动更新(ONUPDATECURRENT_TIMESTAMP)。-在MySQL5.6.5之前,`DATETIME`类型不支持使用`CURRENT_TIMESTAMP`作为默认值。从MySQL5.6.5开始,`DATETIME`类型也可以使用`CURRENT_TIMESTAMP`作为默认值,但需要满足一定的条件。因此,错误可能由以下原因引起:1.使用的MySQL版本低于5.6.5,不支持`DATETIME`的默认值为`CURRENT_TIMESTAMP`。2.即使版本足够,但可能因为SQL_MODE的设置问题导致不允许。解决方案:1.升级MySQL到5.6.5或更高版本(如果可行)。2.如果无法升级,考虑使用`TIMESTAMP`类型代替`DATETIME`类型,因为`TIMESTAMP`在较早版本就支持`CURRENT_TIMESTAMP`默认值。3.如果必须使用`DATETIME`类型且不能升级,那么不能设置默认值为`CURRENT_TIMESTAMP`。可以考虑以下替代方案:a.去掉`NOTNULL`约束,允许为NULL,这样插入时如果不指定值,就会为NULL。然后在应用层处理默认值。b.使用触发器来设置插入时的默认值。但是,根据引用[2]中关于非空约束的创建,我们要求该列非空,因此如果使用方案3a,则不能有非空约束,这可能不符合业务逻辑。因此,我们可能需要修改为:-使用`TIMESTAMP`类型,但注意`TIMESTAMP`的范围是'1970-01-0100:00:01'UTC到'2038-01-1903:14:07'UTC,而`DATETIME`的范围是'1000-01-0100:00:00'到'9999-12-3123:59:59'。如果业务需要超出`TIMESTAMP`范围,则不能使用。-或者使用触发器(在插入前触发,如果新行的该列为空,则设置为当前时间)。另外,引用[3]中的示例是一个SQL注入的例子,与当前问题无关。所以,具体解决方案步骤:方案一:修改列类型为TIMESTAMP(如果时间范围允许)ALTERTABLE表名ADDCOLUMNregistration_datetimeTIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMP;方案二:使用触发器(如果必须用DATETIME且版本低)步骤1:先添加列,允许NULL(因为不能同时有NOTNULL和没有默认值的情况下插入NULL会报错)ALTERTABLE表名ADDCOLUMNregistration_datetimeDATETIMENULL;步骤2:创建一个BEFOREINSERT触发器,当插入时如果该列为NULL,则设置为当前时间。CREATETRIGGERset_registration_datetimeBEFOREINSERTON表名FOREACHROWBEGINIFNEW.registration_datetimeISNULLTHENSETNEW.registration_datetime=NOW();ENDIF;END;步骤3:如果需要确保该列不为空,可以再修改列为NOTNULL(但要注意已有记录,因为已有记录可能为NULL,所以需要先更新已有记录再修改)--首先更新已有记录的该列为当前时间(或某个默认时间)UPDATE表名SETregistration_datetime=NOW()WHEREregistration_datetimeISNULL;--然后修改列为NOTNULLALTERTABLE表名MODIFYCOLUMNregistration_datetimeDATETIMENOTNULL;但是,如果表很大,更新操作可能会很慢,并且触发器会增加插入操作的开销。方案三:升级MySQL版本到5.6.5或以上,然后就可以直接使用DATETIME类型并设置默认值为CURRENT_TIMESTAMP。根据实际情况选择方案。另外,注意在MySQL8.0中,`DATETIME`和`TIMESTAMP`都可以使用`CURRENT_TIMESTAMP`作为默认值,而且还可以使用更精确的默认值,例如`CURRENT_TIMESTAMP(6)`。因此,请先确认MySQL版本。如果用户使用的是较新版本的MySQL但仍然报错,可能是由于SQL_MODE包含`NO_ZERO_DATE`或严格模式等,但更常见的还是版本问题。总结:优先检查MySQL版本,然后根据版本选择解决方案。</think>### 解决方案:添加带默认值的 DATETIME 列报错分析 您的 SQL 语句 `ADD COLUMN registration_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP` 报错的核心原因是:**在 MySQL 中,`DATETIME` 类型列不能直接使用 `CURRENT_TIMESTAMP` 作为默认值**(这与 `TIMESTAMP` 类型不同)。以下是详细解决方案: --- #### 错误原因分析 1. **数据类型限制**(核心原因) - `DATETIME` 类型在 MySQL 中**不支持** `CURRENT_TIMESTAMP` 默认值(仅 `TIMESTAMP` 支持此特性)[^1]。 - 示例:引用中 `TIMESTAMP` 可设置 `DEFAULT CURRENT_TIMESTAMP`,但 `DATETIME` 不行: ```sql created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 有效 registration_datetime DATETIME DEFAULT CURRENT_TIMESTAMP -- 无效! ``` 2. **非空约束冲突** - `NOT NULL` 约束要求列必须有值,但 `DEFAULT` 无效导致插入数据时无法自动填充。 --- #### 解决方案 根据 MySQL 版本选择对应方案: ##### ✅ 方案 1:改用 `TIMESTAMP` 类型(推荐) ```sql ALTER TABLE 表名 ADD COLUMN registration_datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; ``` **优势**: - 直接支持 `CURRENT_TIMESTAMP` 默认值 - 自动填充插入时间 **注意**: - `TIMESTAMP` 范围 (1970-2038) 小于 `DATETIME` (1000-9999),需确保业务时间在此范围内。 --- ##### ✅ 方案 2:使用 `DATETIME` + 触发器(兼容所有版本) ```sql -- 1. 添加允许为空的列 ALTER TABLE 表名 ADD COLUMN registration_datetime DATETIME NULL; -- 2. 创建触发器自动填充时间 DELIMITER $$ CREATE TRIGGER set_registration_time BEFORE INSERT ON 表名 FOR EACH ROW BEGIN IF NEW.registration_datetime IS NULL THEN SET NEW.registration_datetime = NOW(); END IF; END$$ DELIMITER ; -- 3. 修改列为非空(需先填充已有数据) UPDATE 表名 SET registration_datetime = NOW() WHERE registration_datetime IS NULL; ALTER TABLE 表名 MODIFY registration_datetime DATETIME NOT NULL; ``` --- ##### ✅ 方案 3:升级 MySQL 到 5.6.5+ 并修改 SQL_MODE > 适用于 MySQL ≥ 5.6.5 的用户 ```sql -- 调整 SQL_MODE 移除限制 SET GLOBAL sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; -- 重新执行原语句 ALTER TABLE 表名 ADD COLUMN registration_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP; ``` --- #### 避坑指南 1. **版本检查** 执行 `SELECT VERSION();` 确认 MySQL 版本: - ≥ 5.6.5:支持方案 3 - < 5.6.5:仅能用方案 1 或 2 2. **业务时间范围** 若需存储早于 1970 或晚于 2038 的时间,必须选择方案 2(`DATETIME` + 触发器)。 3. **默认值语法** 即使在高版本中,也要确保默认值写为 **`DEFAULT CURRENT_TIMESTAMP`**(非函数式写法)。 --- ### 示例验证 ```sql -- 成功案例(TIMESTAMP类型) ALTER TABLE events ADD COLUMN reg_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; -- 插入测试(自动填充时间) INSERT INTO events (event_name) VALUES ('测试会议'); SELECT * FROM events; -- reg_time 自动填充 ``` > 通过上述方案,可解决因数据类型与默认值不兼容导致的错误。建议优先使用 **方案 1**(`TIMESTAMP`),兼顾简单性与可靠性[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值