1

我正在尝试使用函数的多个返回来更新表。

我创建了一个类型

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
...

我需要更新一个包含城市、州、纬度和经度列的表。使用纬度/经度,我应该调用函数并使用结果来更新城市/州的值。我只想为每一行调用一次函数,并且只有一些行需要更新(假设 city 为 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)
                    );

但我得到一个无效的标识符错误。我觉得我过于复杂了,正确的方法是什么?

4

3 回答 3

2

出现该错误的原因是 Oracle 尝试限定select 语句newcity中引用的内容。SELECT newcity.city, newcity.state它找不到对象newcity,因此引发错误。还为内联视图设置别名,就t1好像您真的需要它一样。正如@Rene提到的,您可以成功地将其替换为表名。为此,您可以按如下方式重写您的更新语句:

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 
于 2012-11-27T06:35:58.863 回答
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
于 2012-11-27T06:35:16.163 回答
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)
                    );
于 2012-11-27T06:47:56.697 回答