Symfony使用ULID时executeQuery执行删除无效无报错问题
Symfony ULID关联DELETE操作无生效问题
问题背景
Symfony项目开发中,针对ULID格式的ID执行DELETE删除请求时操作未生效,系统未抛出任何报错。
初始实现代码
$this->connexion->executeQuery(' DELETE FROM plant_periode WHERE plant_id = :plantId ', [ 'plantId' => $plant->getId() ]);
项目ULID主键定义
项目通过UlidTrait定义ULID类型主键,实现代码如下:
/** * Trait UuidTrait */ trait UlidTrait { /** * @ORM\Id * @ORM\Column(type="ulid", unique=true) * @ORM\GeneratedValue(strategy="CUSTOM") * @ORM\CustomIdGenerator(class="doctrine.ulid_generator") */ protected $id; /** * getId */ public function getId(): ?Ulid { return $this->id; } }
已尝试的修复方案
尝试将ULID转换为二进制格式,同时指定参数类型为ParameterType::BINARY后执行删除,代码如下:
$this->connexion->executeQuery(' DELETE FROM plant_periode WHERE plant_id = :plantId ', [ 'plantId' => $plant->getId()->toBinary() ], [ 'plantId' => ParameterType::BINARY ]);
该方案执行后仍未达到预期删除效果。
可行解决思路
- 核对关联字段存储格式:Doctrine ULID类型支持26位Base32字符串、16字节二进制两种存储模式。如果
plant_periode表的plant_id字段为字符串存储,直接传入ULID对象、二进制内容都会因类型不匹配无法命中数据行,最终执行删除无效果也不报错。该场景下直接传入ULID字符串值,指定参数类型为字符串即可:
$this->connexion->executeQuery(' DELETE FROM plant_periode WHERE plant_id = :plantId ', [ 'plantId' => $plant->getId()->toBase32() ], [ 'plantId' => ParameterType::STRING ]);
- 若字段为二进制存储,核对字段长度定义:ULID转二进制后固定占16字节,需确认
plant_id字段定义为BINARY(16),字段长度不匹配会导致二进制内容比对失败,无法命中待删除行。 - 优先使用Doctrine封装的查询方法执行操作:手写原生SQL时很容易遗漏参数类型匹配,改用DQL或QueryBuilder执行删除时,Doctrine会根据实体字段映射自动处理参数类型转换,避免手动传参的类型错误,示例写法:
$entityManager->createQueryBuilder() ->delete(PlantPeriode::class, 'pp') ->where('pp.plant = :plant') ->setParameter('plant', $plant) ->getQuery() ->execute();
- 执行操作后输出影响行数定位问题:调用
executeQuery后通过rowCount()方法获取受影响的行数,如果返回值为0,说明参数和数据库存储内容不匹配,直接排查参数类型、字段存储格式的一致性即可,无需优先排查SQL语法逻辑。
内容的提问来源于stack exchange,提问作者dipin
相关产品推荐
相关产品推荐

