2014-03-18 81 views
2

當我運行此查詢:SQL更新標量函數

UPDATE myTable SET x = (SELECT round(random()*100)); 

所有記錄有x相同的值。這是有道理的。

當我運行此查詢:

UPDATE myTable SET x = round(random()*100); 

它更新所有表中的記錄,併爲每條記錄的x值是不同的。

我想知道第二個查詢在後臺發生了什麼。它是否爲每個記錄ID(1 .... n)運行更新查詢?

我猜測它的工作原理類似於觸發器,其中的每一行更新

  1. 觸發攔截
  2. 調用x的功能,並將值之前
  3. 執行查詢

究竟發生了什麼?

回答

3

這很簡單,真的。函數random()定義爲VOLATILE

如果將其放入子查詢中,則可以使用單個行生成派生表。 Postgres可以實現結果並在外部查詢中多次使用它。

否則Postgres會爲每一行調用函數。這就是VOLATILE函數必須被處理的方式。 Per documentation on function volatility

A VOLATILE函數可以做任何事情,包括修改數據庫。 它可以在相同的 參數的連續調用中返回不同的結果。優化器不會對這些函數的行爲做任何假設。 使用易失性函數的查詢將在需要其值的每一行處重新評估 函數。

大膽重視我的。