MySQL 存储过程的“第 1 行 'in_operation' 列的数据被截断”问题
'Data truncated for column 'in_operation' at row 1' issue with MySQL stored procedure
我一直在努力解决一些 MySQL 存储过程的奇怪问题。
定义如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `search_audit`(
IN in_audit_search_type ENUM('USER','IP','HOSTNAME', 'SHARE', 'OPERATION', 'SOURCE', 'DESTINATION', 'ALL'),
IN in_user_name VARCHAR(32),
IN in_client_ip VARCHAR(15),
IN in_host_name VARCHAR(32),
IN in_share_name VARCHAR(32),
IN in_operation VARCHAR(24),
IN in_affected_item VARCHAR(8192),
IN in_new_name VARCHAR(8192),
IN in_start_date DATETIME,
IN in_end_date DATETIME)
BEGIN
CASE in_audit_search_type
WHEN 'USER'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
user_name = in_user_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'IP'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
client_ip = in_client_ip AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'HOSTNAME'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
host_name = in_host_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'SHARE'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
share_name = in_share_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'OPERATION'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
operation = in_operation AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'SOURCE'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
affected_item = in_affected_item AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'TARGET'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
new_name = in_target AND
log_time BETWEEN in_start_date AND in_end_date;
ELSE
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
`operation`,
affected_item,
new_name
FROM
audit
WHERE
log_time BETWEEN in_start_date AND in_end_date;
END CASE;
END
我正在尝试从我一直在尝试编写的某个 C# 应用程序中调用此存储过程。这是 C# 存储过程对象的定义:
SEARCH_AUDIT_COMMAND = new MySqlCommand();
SEARCH_AUDIT_COMMAND.CommandType = System.Data.CommandType.StoredProcedure;
SEARCH_AUDIT_COMMAND.Connection = DB_CONNECTION;
SEARCH_AUDIT_COMMAND.CommandText = "search_audit";
SEARCH_AUDIT_COMMAND.CommandTimeout = 300;
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_audit_search_type", MySqlDbType.Enum);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_user_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_client_ip", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_host_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_share_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_operation", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_affected_item", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_new_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_start_date", MySqlDbType.DateTime);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_end_date", MySqlDbType.DateTime);
这是我检索记录的方法:
internal BindingList<AuditRecord> SearchAuditRecords(
AuditSearchType searchType,
string inUserName,
string inClientIP,
string inHostName,
string inShareName,
string inOperation,
string inAffectedItem,
string inNewName,
DateTime startDate,
DateTime endDate)
{
SEARCH_AUDIT_COMMAND.Parameters["@in_audit_search_type"].Value = searchType.ToString();
SEARCH_AUDIT_COMMAND.Parameters["@in_user_name"].Value = inUserName;
SEARCH_AUDIT_COMMAND.Parameters["@in_client_ip"].Value = inClientIP;
SEARCH_AUDIT_COMMAND.Parameters["@in_host_name"].Value = inHostName;
SEARCH_AUDIT_COMMAND.Parameters["@in_share_name"].Value = inShareName;
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = inOperation;
SEARCH_AUDIT_COMMAND.Parameters["@in_affected_item"].Value = inAffectedItem;
SEARCH_AUDIT_COMMAND.Parameters["@in_new_name"].Value = inNewName;
SEARCH_AUDIT_COMMAND.Parameters["@in_start_date"].Value = startDate;
SEARCH_AUDIT_COMMAND.Parameters["@in_end_date"].Value = endDate;
DB_CONNECTION.Open();
MySqlDataReader reader = SEARCH_AUDIT_COMMAND.ExecuteReader();
BindingList<AuditRecord> records = new BindingList<AuditRecord>();
while (reader.Read())
{
DateTime logDate = reader.GetDateTime(0);
string userName = reader.GetString(1);
string clientIP = reader.GetString(2);
string hostName = reader.GetString(3);
string shareName = reader.GetString(4);
string operation = reader.GetString(5);
string affectedItem = reader.GetString(6);
string newName = reader.GetString(7);
AuditRecord temp = new AuditRecord(logDate,userName, clientIP, hostName, shareName, operation, affectedItem, newName);
records.Add(temp);
}
DB_CONNECTION.Close();
return records;
}
当我调用这个方法时,我得到这个异常:
MySql.Data.MySqlClient.MySqlException: 'Data truncated for column 'in_operation' at row 1'
但是如果我删除这一行,它会起作用:
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = inOperation;
如果我像这样编辑该行,它也有效:
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = null;
这是“审计”table创建语句:
CREATE TABLE `audit` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`log_time` datetime DEFAULT NULL,
`user_name` varchar(32) DEFAULT NULL,
`client_ip` varchar(15) DEFAULT NULL,
`host_name` varchar(32) DEFAULT NULL,
`share_name` varchar(32) DEFAULT NULL,
`operation` varchar(32) DEFAULT NULL,
`affected_item` varchar(8192) DEFAULT NULL,
`new_name` varchar(8192) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `USER` (`user_name`,`share_name`,`operation`),
KEY `SHARE` (`share_name`,`user_name`,`operation`),
KEY `OPERATION` (`operation`,`user_name`,`share_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我一直在绞尽脑汁试图理解为什么会抛出异常。我已经在互联网上搜索了答案。我现在正在考虑自杀。
发生截断是因为在过程中您将 in_operation
声明为 VARCHAR(24)
,但创建 table 语句中的 operation
列是 VARCHAR(32)
。要修复此更改,请将过程声明中的 VARCHAR(24)
替换为 VARCHAR(32)
:
{...}
IN in_operation VARCHAR(32),
{...}
我一直在努力解决一些 MySQL 存储过程的奇怪问题。
定义如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `search_audit`(
IN in_audit_search_type ENUM('USER','IP','HOSTNAME', 'SHARE', 'OPERATION', 'SOURCE', 'DESTINATION', 'ALL'),
IN in_user_name VARCHAR(32),
IN in_client_ip VARCHAR(15),
IN in_host_name VARCHAR(32),
IN in_share_name VARCHAR(32),
IN in_operation VARCHAR(24),
IN in_affected_item VARCHAR(8192),
IN in_new_name VARCHAR(8192),
IN in_start_date DATETIME,
IN in_end_date DATETIME)
BEGIN
CASE in_audit_search_type
WHEN 'USER'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
user_name = in_user_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'IP'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
client_ip = in_client_ip AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'HOSTNAME'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
host_name = in_host_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'SHARE'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
share_name = in_share_name AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'OPERATION'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
operation = in_operation AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'SOURCE'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
affected_item = in_affected_item AND
log_time BETWEEN in_start_date AND in_end_date;
WHEN 'TARGET'
THEN
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
operation,
affected_item,
new_name
FROM
audit
WHERE
new_name = in_target AND
log_time BETWEEN in_start_date AND in_end_date;
ELSE
SELECT
log_time,
user_name,
client_ip,
host_name,
share_name,
`operation`,
affected_item,
new_name
FROM
audit
WHERE
log_time BETWEEN in_start_date AND in_end_date;
END CASE;
END
我正在尝试从我一直在尝试编写的某个 C# 应用程序中调用此存储过程。这是 C# 存储过程对象的定义:
SEARCH_AUDIT_COMMAND = new MySqlCommand();
SEARCH_AUDIT_COMMAND.CommandType = System.Data.CommandType.StoredProcedure;
SEARCH_AUDIT_COMMAND.Connection = DB_CONNECTION;
SEARCH_AUDIT_COMMAND.CommandText = "search_audit";
SEARCH_AUDIT_COMMAND.CommandTimeout = 300;
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_audit_search_type", MySqlDbType.Enum);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_user_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_client_ip", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_host_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_share_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_operation", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_affected_item", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_new_name", MySqlDbType.VarChar);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_start_date", MySqlDbType.DateTime);
SEARCH_AUDIT_COMMAND.Parameters.Add("@in_end_date", MySqlDbType.DateTime);
这是我检索记录的方法:
internal BindingList<AuditRecord> SearchAuditRecords(
AuditSearchType searchType,
string inUserName,
string inClientIP,
string inHostName,
string inShareName,
string inOperation,
string inAffectedItem,
string inNewName,
DateTime startDate,
DateTime endDate)
{
SEARCH_AUDIT_COMMAND.Parameters["@in_audit_search_type"].Value = searchType.ToString();
SEARCH_AUDIT_COMMAND.Parameters["@in_user_name"].Value = inUserName;
SEARCH_AUDIT_COMMAND.Parameters["@in_client_ip"].Value = inClientIP;
SEARCH_AUDIT_COMMAND.Parameters["@in_host_name"].Value = inHostName;
SEARCH_AUDIT_COMMAND.Parameters["@in_share_name"].Value = inShareName;
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = inOperation;
SEARCH_AUDIT_COMMAND.Parameters["@in_affected_item"].Value = inAffectedItem;
SEARCH_AUDIT_COMMAND.Parameters["@in_new_name"].Value = inNewName;
SEARCH_AUDIT_COMMAND.Parameters["@in_start_date"].Value = startDate;
SEARCH_AUDIT_COMMAND.Parameters["@in_end_date"].Value = endDate;
DB_CONNECTION.Open();
MySqlDataReader reader = SEARCH_AUDIT_COMMAND.ExecuteReader();
BindingList<AuditRecord> records = new BindingList<AuditRecord>();
while (reader.Read())
{
DateTime logDate = reader.GetDateTime(0);
string userName = reader.GetString(1);
string clientIP = reader.GetString(2);
string hostName = reader.GetString(3);
string shareName = reader.GetString(4);
string operation = reader.GetString(5);
string affectedItem = reader.GetString(6);
string newName = reader.GetString(7);
AuditRecord temp = new AuditRecord(logDate,userName, clientIP, hostName, shareName, operation, affectedItem, newName);
records.Add(temp);
}
DB_CONNECTION.Close();
return records;
}
当我调用这个方法时,我得到这个异常:
MySql.Data.MySqlClient.MySqlException: 'Data truncated for column 'in_operation' at row 1'
但是如果我删除这一行,它会起作用:
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = inOperation;
如果我像这样编辑该行,它也有效:
SEARCH_AUDIT_COMMAND.Parameters["@in_operation"].Value = null;
这是“审计”table创建语句:
CREATE TABLE `audit` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`log_time` datetime DEFAULT NULL,
`user_name` varchar(32) DEFAULT NULL,
`client_ip` varchar(15) DEFAULT NULL,
`host_name` varchar(32) DEFAULT NULL,
`share_name` varchar(32) DEFAULT NULL,
`operation` varchar(32) DEFAULT NULL,
`affected_item` varchar(8192) DEFAULT NULL,
`new_name` varchar(8192) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `USER` (`user_name`,`share_name`,`operation`),
KEY `SHARE` (`share_name`,`user_name`,`operation`),
KEY `OPERATION` (`operation`,`user_name`,`share_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我一直在绞尽脑汁试图理解为什么会抛出异常。我已经在互联网上搜索了答案。我现在正在考虑自杀。
发生截断是因为在过程中您将 in_operation
声明为 VARCHAR(24)
,但创建 table 语句中的 operation
列是 VARCHAR(32)
。要修复此更改,请将过程声明中的 VARCHAR(24)
替换为 VARCHAR(32)
:
{...}
IN in_operation VARCHAR(32),
{...}