如何将含表变量的存储过程调用SQL转换为TypeORM createQueryBuilder写法
错误原因
你遇到的Must declare the scalar variable @user报错有两个核心问题:
- TypeORM 默认每次调用
query方法、执行QueryBuilder都是独立的数据库会话,你在第一次query中声明的@user表变量仅存在于当前会话,后续操作切换了会话自然无法识别该变量。 - 你用QueryBuilder执行
.into(@user)时,@user是数据库侧的表类型变量,不是你映射的物理实体表,QueryBuilder无法直接识别该变量作为插入目标。
最优解决方案
直接将三条SQL语句合并为同一次query调用,同时使用参数化传值避免你原有拼接字符串写法带来的SQL注入风险,修改后的Service代码如下:
class UserTools{ constructor(@InjectRepository(User) private userRepo: Repository<User>) {} async insertUserData(body){ try { // 同一会话内执行所有SQL,参数化传值更安全 const spResult = await this.userRepo.manager.query(` DECLARE @user AS dsschema.user_tools; INSERT INTO @user VALUES(@userId, @toolId); EXECUTE dsschema.sp_user_tool @user; `, [body.user_id, body.tool_id]); return spResult; } catch (error) { throw error; } } }
你现有的user.entity.ts是对应物理用户表的实体,和存储过程用到的表类型dsschema.user_tools无关联,不需要修改。
内容的提问来源于stack exchange,提问作者V_S
相关产品推荐
相关产品推荐

