如何移除SQL INSERT语句中值为空字符串('')的对应字段与值?
解决SQL INSERT语句移除空字符串字段及对应值的问题
需求说明
需要从SQL INSERT语句中移除值为空字符串('')的对应字段及其对应值,确保处理后字段和值的数量严格匹配。
示例
原SQL语句:
insert into `invoices_payments` (`invoice_id`, `finance_id`, `employee_id`, `shift_id`, `point_of_sale_id`, `debtor_id`, `creditor_id`, `debit`, `retroactive`, `updated_at`, `created_at`) values ( '101010044', '', '10100000', '1010000', '1', '70', '41', '89', '', '2023-09-27 10:22:25', '2023-09-27 10:22:25' ) ;
处理后期望结果:
insert into `invoices_payments` (`invoice_id`, `employee_id`, `shift_id`, `point_of_sale_id`, `debtor_id`, `creditor_id`, `debit`, `updated_at`, `created_at`) values ( '101010044', '10100000', '1010000', '1', '70', '41', '89', '2023-09-27 10:22:25', '2023-09-27 10:22:25' ) ;
原方法的问题
你之前尝试的PHP函数直接按逗号分割整个SQL语句,无法区分字段列表和值列表的边界,导致字段与值的对应关系丢失,最终出现数量不匹配的问题:
function processSqlStatement($sqlStatement) { // Split the SQL statement into individual key-value pairs $pairs = explode(',', $sqlStatement); // Initialize an array to store valid key-value pairs $validPairs = []; foreach ($pairs as $pair) { // Check if the pair contains an empty single quote ('') or is empty after trimming if (strpos($pair, "''") === false && trim($pair) !== '') { // If not, add it to the valid pairs array $validPairs[] = trim($pair); // Trim to remove extra spaces } } // Join the valid pairs back into a single SQL statement using comma and space $modifiedSqlStatement = implode(', ', $validPairs); return $modifiedSqlStatement; }
正确实现方案
核心思路是分别提取字段列表和值列表,找到值为空字符串的位置后,同步移除对应位置的字段和值,最后拼接回完整的SQL语句:
function processSqlInsert($sql) { // 正则匹配提取INSERT语句中的关键部分 if (!preg_match('/insert into\s+`?(\w+)`?\s*\((.*?)\)\s*values\s*\((.*?)\)\s*;/is', $sql, $matches)) { return $sql; // 不匹配INSERT格式则返回原SQL } $tableName = $matches[1]; $fieldsRaw = $matches[2]; $valuesRaw = $matches[3]; // 拆分并清洗字段和值(去除多余空格、换行) $fields = array_map('trim', explode(',', $fieldsRaw)); $values = array_map('trim', explode(',', $valuesRaw)); // 字段和值数量不一致时直接返回原SQL if (count($fields) !== count($values)) { return $sql; } $validFields = []; $validValues = []; // 同步过滤空值对应的字段和值 foreach ($values as $index => $value) { if ($value !== "''") { $validFields[] = $fields[$index]; $validValues[] = $value; } } // 拼接处理后的SQL,保留基本格式 $newFieldsStr = implode(', ', $validFields); $newValuesStr = implode(', ', $validValues); return "insert into `{$tableName}` ({$newFieldsStr}) values ( {$newValuesStr} ) ;"; } // 使用示例 $originalSql = "insert into `invoices_payments` (`invoice_id`, `finance_id`, `employee_id`, `shift_id`, `point_of_sale_id`, `debtor_id`, `creditor_id`, `debit`, `retroactive`, `updated_at`, `created_at`) values ( '101010044', '', '10100000', '1010000', '1', '70', '41', '89', '', '2023-09-27 10:22:25', '2023-09-27 10:22:25' ) ;"; echo processSqlInsert($originalSql);
代码说明
- 精准匹配:用正则表达式定位INSERT语句的表名、字段区和值区,避免全局分割导致的结构混乱。
- 同步过滤:遍历值列表时,同步保留对应位置的字段,确保字段和值的数量始终一致。
- 格式兼容:拼接时尽量保留原SQL的换行结构,保证处理后的语句可读性。
内容的提问来源于stack exchange,提问作者ُEslam Talabe Garibe Qoutbe
相关产品推荐
相关产品推荐

