2016-09-03 3 views
0

id를 새 값으로 바꾸려면 테이블 t1이 필요합니다.PostgreSQL : 왜이 ​​업데이트가 제대로 작동하지 않습니까?

두 번째 테이블 t_changes는 대체 문자 old_id-> new_id를 포함합니다. 하지만 업데이트 할 때 t1에는 모든 레코드에 대해 동일한 새 ID 값이 포함됩니다. 올바르지 않은 것은 무엇입니까? 동일한 업데이트가 T-SQL에서 성공적으로 작동합니다.

drop table t1; 
drop table t2; 
drop table t_changes; 

create table t1 
(id INT,name text, new_id INT default(0)); 

create table t_changes 
(old_id INT,new_id int) 

insert into t1(id,NAME) 
VALUES (1,'n1'),(2,'n2'),(3,'n3'); 

insert into t_changes(old_id,new_id) 
values(1,11),(2,12),(3,13),(4,13) 

select * from t1; 
select * from t_changes; 

-------!!!! 
update t1 
set new_id = n.new_id 
from t1 t 
inner join t_changes n 
on n.old_id=t.id; 

select * from t1 
------------------------------ 
"id" "name" "new_id" 
----------------- 
"1" "n1" "11" 
"2" "n2" "11" 
"3" "n3" "11" 

답변

1

이것은 당신의 포스트 그레스 update 문 :

update t1 
    set new_id = n.new_id 
    from t1 t inner join 
     t_changes n 
     on n.old_id = t.id; 

문제는 updatet1from의 다른 t1을 의미한다는 것이다. 당신은 그들이 동일한 참조가되도록 의도합니다.

update t1 
    set new_id = n.new_id 
    from t_changes n 
    where n.old_id = t.id; 

구문이 다른 일부 데이터베이스 (예 : SQL Server)에서 지원하는 구문과 매우 유사합니다. 그러나 그들을 위해, 당신은 업데이트에 테이블 별칭를 사용해야합니다 :

update t 
    set new_id = n.new_id 
    from t1 t inner join 
     t_changes n 
     on n.old_id = t.id; 
+0

좋아, thnx합니다. 당신 말이 맞아요. PostgreSQL에 SQL Server 비즈니스 로직을 포팅 할 때 그 문제가 발생합니다. 이 문은 T-SQL에서 작동하지만 PostgreSQL에서는 예상대로 작동하지 않습니다. 나는이 같은 모든 업데이 트 stmts을 검토해야합니다. – Oleg

+0

@Oleg : [매뉴얼에 기재되어 있습니다] (https://www.postgresql.org/docs/current/static/sql-update.html#AEN88864) : "* 타겟 테이블이 from_list, 자기 조인을 원하지 않는 한 * " –

+0

@Oleg. . . 'FROM' 절에서't1'에 별칭't'가 주어지기 때문에 쿼리가 SQL Server에서 제대로 작동하지 않았습니다. 'UPDATE'는 별칭 대신 테이블 이름을 사용합니다 (실제 쿼리에는이 문제가 없음). –

1

방법 대신이 일에 대해 : t1의 일부 행에 대해 t_changes에 해당하는 행이없는 경우,이 NULLt1.new_id을 변경됩니다

update t1 
set new_id = (SELECT new_id FROM t_changes WHERE old_id=id); 

참고.

관련 문제