Sql-Server

如何使用複雜的更新查詢,更新兩個表中的值

  • July 11, 2017

此更新程式碼顯示錯誤:我需要通過單個更新查詢更新兩個表中的性別列

UPDATE 
   studentbase a, studentprofile b 
SET  
   a.gender='FEMALE', 
   b.gender='FEMALE' 
FROM 
   studentbase a, studentprofile b 
WHERE 
   a.applicationnumber=b.applicationnumber AND 
   a.applicationnumber=12345;

在 Microsoft SQL Server 中,直接的方法可能是在表上創建觸發器腳本

$$ studentbase $$立即複製$$ gender $$列到表$$ studentprofile $$. 如果您以前沒有這樣做,這需要適度的照顧。 一種不太直接但不是特別好的方法是在連接的表上創建一個視圖,並在您對視圖執行更新時,在兩個表上一個接一個地執行更新的而不是觸發器。這可以解決兩個表中的許多列。

一個非常古怪的方法,我沒有完全掌握,但我認為它會起作用,就是讓

$$ studentbase $$和$$ studentprofile $$位於(應用程序編號,性別)的鍵上,並在需要的任何位置放置“ON UPDATE CASCADE”字樣 - 請原諒我查找它 - 這樣當您更改$$ gender $$在$$ studentbasic $$,它被認為是外鍵值的更改,必須自動應用於$$ studentprofile $$也是。我認為這不是該功能的用途,而是只有您才能理解您所做的事情的好處:-)(除非您想讓某人變得困難,否則這並不是一件好事接管你的工作。) 可能還有其他方法。

正如@joanolo 所說,“正常”方法是將列放在一個表中,並在需要查看數據時加入另一個表

$$ studentbasic $$連同來自的數據$$ studentprofile $$. 我猜這還沒有完成,或者是因為(1)表格被複製到不同的地方以供參考,或者(2)不允許使用者查看兩組數據,或者(3)表格是設計的由主要使用 Microsoft Excel 工作的經理。我無法評論 1 和 3,但情況 2 可以通過再次使用視圖在 Microsoft SQL 中解決;您允許使用者訪問僅顯示允許他們從兩個表中查看的數據的視圖,而不授予他們訪問表的權限 - 那麼他們所能做的就是使用該視圖。 或者,您可能是一名試圖解決課堂練習或在大學記錄中開玩笑的學生。:-)

在 PostgreSQL 中,你可以使用WITH查詢來做這樣的事情:

-- A change of mind...
WITH first_update AS
(
   UPDATE 
       studentbase
   SET
       gender = 'FEMALE'
   WHERE
       applicationnumber = 12345
   RETURNING
       applicationnumber, gender
)
UPDATE
   studentprofile
SET
   gender = first_update.gender
FROM
   first_update
WHERE
   studentprofile.applicationnumber = first_update.applicationnumber ;

您可以利用 PostgreSQL可以在一個WITH(AFAIK 不是標準 SQL)中更新表這一事實,再加上您可以從中獲取一些RETURNING數據(同樣,非標準 SQL)的事實,並使用這些數據進行第二次更新。

請注意,您只需要編寫一次參數(12345, ‘FEMALE’)。

您可以在此處**查看dbfiddle的整個設置


注意:我不會做這種事情。我會嘗試將數據標準化而不是多餘的。出於性能或安全原因,很少有這種事情應該做的場景。

您使用這種類型的結構(WITH RETURNING …),在某些情況下,當您想要將INSERT數據放入表中並獲取您用來進入的代理鍵(a或SERIALaUUID或其他一些自動生成的 id)INSERT一個代理表。


作為替代方案(也可以在大多數其他數據庫中實現,並進行足夠的語法更改),您可以編寫一個儲存過程(在 PostgreSQL 中,它們實際上是User-defined Functions,做同樣的事情:

CREATE FUNCTION 
   set_student_gender (in _applicationnumber integer, in _gender text)
RETURNS
   void
AS
$body$
BEGIN
   UPDATE studentbase SET gender = _gender WHERE applicationnumber = _applicationnumber ;
   UPDATE studentprofile SET gender = _gender WHERE applicationnumber = _applicationnumber ;
   RETURN ;
END ;
$body$
LANGUAGE PLPGSQL ;

…你會使用

SELECT
   set_student_gender(12345, 'FEMALE') ;

dbfiddle在這裡


作為第二種選擇:使用觸發器,正如@Robert Carnegie已經建議的那樣。原理是一樣的,只是使用不同的SQL RDBMS時觸發函式的語法不同。

引用自:https://dba.stackexchange.com/questions/179541