Supabase执行UPDATE查询报错:需WHERE子句(错误码21000)
问题:Supabase更新操作返回"UPDATE requires a WHERE clause"错误
我正在用Supabase开发大学作业的快速MVP,需要实现反馈功能来更新行中部分列,编写的JS查询如下:
const { error: updateError } = await supabase.from('route').update({ total_score: 5 }).eq('id', 1);
执行后返回400错误,错误详情:
{"code":"21000","details":null,"hint":null,"message":"UPDATE requires a WHERE clause"}
Supabase中没有任何数据更新,此前该查询可正常运行,现在无法使用。关闭RLS后问题仍存在。
补充信息
调用更新查询的函数
async function setRating() { const rate = range.value.value const { error: updateError } = await supabase.from('route').update({ total_score: 5 }).eq('id', 1); console.log(updateError); // 因查询失效已注释后续逻辑 // if (!update_error) { // console.log(update); // route_feedback.value.classList.add('hide') // route_ended.value.classList.add('show') // setTimeout(() => { // route_feedback.value.classList.remove('show') // route_feedback.value.classList.remove('hide') // }, 500); // } } }
route表的RLS策略
- 策略名
allow_update_on_route,目标角色public,USING表达式true,WITH CHECK表达式true - 策略名
Authorized users can select from route table,目标角色public,USING表达式(auth.role() = 'authenticated'::text)
route表定义
create table public.route ( id bigint generated by default as identity not null, name text null, country text null, city text null, description text null, imageName text null, created_at timestamp with time zone null default now(), total_reviews numeric null, total_score numeric null, duration numeric not null default '30'::numeric, rating double precision null, isAdult boolean not null default false, constraint route_pkey primary key (id) ) tablespace pg_default; create trigger update_route_rating_trigger after insert or update on route for each row execute function update_route_rating ();
update_route_rating函数定义
BEGIN IF pg_trigger_depth() <> 1 THEN RETURN NEW; END IF; UPDATE route SET rating = ROUND((total_score / total_reviews), 1); return new; END;
解决方案
问题出在update_route_rating触发器函数里:函数中的UPDATE route SET rating = ...语句没有添加WHERE条件,会尝试更新整个route表,而PostgreSQL默认禁止无WHERE子句的全表更新操作,因此抛出错误。
修改触发器函数,添加WHERE条件限定只更新当前操作的行:
BEGIN IF pg_trigger_depth() <> 1 THEN RETURN NEW; END IF; UPDATE route SET rating = ROUND((total_score / total_reviews), 1) WHERE id = NEW.id; return new; END;
修改后,触发器只会更新刚刚被插入或修改的那一行(通过NEW.id获取当前行ID),既符合业务逻辑(仅更新对应行的评分),也避免了全表更新的限制,JS查询即可正常执行。
内容的提问来源于stack exchange,提问作者Scheffio
相关产品推荐
相关产品推荐

