2012-11-27 77 views
1

我試圖用函數的多個返回來更新表。使用返回多個值的函數更新多列

我已經創建了一個TYPE

CREATE OR REPLACE TYPE city_state AS OBJECT 
(
    city VARCHAR2(30), 
    state VARCHAR2(2) 
); 
/

和我有一個返回此類型的變量的函數。

CREATE OR REPLACE FUNCTION closestcity(lat IN NUMBER, lon IN NUMBER) RETURN city_state IS 
... 

我需要更新包含城市,州,緯度和經度列的表格。對於經緯度,我應該調用函數並使用結果來更新城市/州的值。我只希望一次調用的函數爲每一行和只有某些行,我需要更新(比方說城市是NULL)

這是我走到這一步,

UPDATE (SELECT * FROM t t1 WHERE city IS NULL) 
SET (city, state) = (
        SELECT newcity.city, newcity.state FROM 
         (SELECT closestcity(latitude, longitude) newcity 
         FROM t t2 
         WHERE t1.latitude = t2.latitude AND 
           t1.longitude = t2.longitude) 
        ); 

,但我得到無效的識別錯誤。我覺得我太過於複雜,對此會採取什麼正確的方法?

回答

2

你已經得到了錯誤的原因,是因爲甲骨文試圖資格newcitySELECT newcity.city, newcity.state select語句引用。它無法找到對象newcity並因此引發錯誤。如果您真的需要,還可以將內聯視圖替換爲t1。作爲@Rene has mentioned,您可以成功使用表名替換它。爲此,如下所示,你可以重寫你的更新語句:

UPDATE (SELECT * FROM t t1 WHERE city IS NULL) t1 
    SET (city, state) = (
         SELECT closestcity(latitude, longitude).city 
           , closestcity(latitude, longitude).state 
          FROM t t2 
          WHERE t1.latitude = t2.latitude 
          AND t1.longitude = t2.longitude 
         ); 

或者乾脆:

UPDATE t t1 
    SET city = closestcity(latitude, longitude).city 
    , state = closestcity(latitude, longitude).state 
where t1.city is null 

更新#1

update (select nd.newdata.city as newcity 
      , nd.newdata.state as newstate 
      , city 
      , state 
      from (        
       SELECT closestcity(latitude, longitude) newdata 
         , city 
         , state 
        FROM t 
        where city is null 
       ) nd 
      ) q 
set q.city = q.newcity 
    , q.state = q.newstate 
+0

這個工程,但我最終打電話給nearestcity兩次 - 這是一個非常沉重的功能 – iomartin

+0

@iomartin我已經更新了答案 –

+0

太棒了,它的工作原理。謝謝! – iomartin

0

的語法應爲:

UPDATE <table1> 
set (<column1>, <column2>) = (select <column1>,<column2> 
           from <table2> 
           where <where clause table2 >) 
where <where clause table1> 

所以您的查詢應該是:

UPDATE t1 
SET (city, state) = (SELECT closestcity(latitude, longitude) newcity 
          ,state 
         FROM t t2 
         WHERE t1.latitude = t2.latitude 
         AND t1.longitude = t2.longitude) 
where city IS NULL 
+0

狀態是一個變量新城市(就像城市一樣),我不能直接選擇它 – iomartin

+0

啊,我已經在想這個了。 – Rene

0

只改變一個

UPDATE (SELECT * FROM t WHERE city IS NULL) **t1** 
SET (city, state) = (
        SELECT newcity.city, newcity.state FROM 
         (SELECT closestcity(latitude, longitude) newcity 
         FROM t t2 
         WHERE t1.latitude = t2.latitude AND 
           t1.longitude = t2.longitude) 
        ); 
+0

我得到'ORA-00904:「T1」。「LONGITUDE」:無效標識符 ' – iomartin