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

都市、州、緯度、経度の列を含むテーブルを更新する必要があります。緯度/経度を使用して、関数を呼び出し、その結果を使用して都市/州の値を更新する必要があります。行ごとに関数を1回だけ呼び出したいのですが、更新する必要がある行はいくつかあります(都市が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 に答える