Oracle 12 c - Неоднозначный столбец в Вставить в выбранный запрос, ORA-00918 - PullRequest
1 голос
/ 07 февраля 2020

Я пытаюсь выполнить множественную вставку с одним оператором, чтобы добиться этого, я использую Вставить в оператор выбора. Но я сталкиваюсь, когда два столбца имеют одинаковое значение при вставке. Я получаю сообщение об ошибке: ORA-00918: column ambiguously defined.

Запрос

INSERT INTO sample (
    HOST,
    TOTAL_PING,
    TOTAL_UNAVAILABLE_PING
)

SELECT * FROM (

    SELECT 'FR3158-73-1',
    82,
    82
    FROM DUAL
    UNION ALL

    SELECT 'FR3158-76-2',
    80,
    10
    FROM DUAL
)

Проблема в первом операторе выбора, где два значения 82 и 82, если я изменил одно значение на что-то работает. Я не знаю, как заставить это работать, даже если значения столбцов одинаковы.

--- Обновления ---

Определение таблицы

CREATE TABLE sample
(
  ID                      NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1) PRIMARY KEY,
  HOST                    VARCHAR2(15 BYTE),
  TOTAL_PING              INTEGER,
  TOTAL_UNAVAILABLE_PING  INTEGER,
  ADDED_ON                TIMESTAMP(6)          DEFAULT systimestamp
);

Ответы [ 3 ]

5 голосов
/ 07 февраля 2020

В этом случае вам не нужен подзапрос - как показало @Littlefoot. Но если вы сделали это в более сложном сценарии, вы можете избежать ошибки, создав псевдонимы выражений столбцов в подзапросе:

INSERT INTO sample (
    HOST,
    TOTAL_PING,
    TOTAL_UNAVAILABLE_PING
)

SELECT * FROM (

    SELECT 'FR3158-73-1' as host,
    82 as total_ping,
    82 as total_unavailable_ping 
    FROM DUAL
    UNION ALL

    SELECT 'FR3158-76-2',
    80,
    10
    FROM DUAL
)
/

2 rows inserted.

Проблема заключается в том, что подзапрос сам по себе получает псевдонимы столбцов. , полученное из значений в первой ветви запроса:

SELECT 'FR3158-73-1',
82,
82 
FROM DUAL
UNION ALL

SELECT 'FR3158-76-2',
80,
10
FROM DUAL

'FR3158-73-         82         82
----------- ---------- ----------
FR3158-73-1         82         82
FR3158-76-2         80         10

Второй и третий столбцы называются "82", что является неоднозначностью, на которую жалуется ORA-00918, с внешней стороны select. Если вы добавляете псевдонимы, которые исчезают:

SELECT 'FR3158-73-1' as host,
82 as total_ping,
82 as total_unavailable_ping 
FROM DUAL
UNION ALL

SELECT 'FR3158-76-2',
80,
10
FROM DUAL

HOST        TOTAL_PING TOTAL_UNAVAILABLE_PING
----------- ---------- ----------------------
FR3158-73-1         82                     82
FR3158-76-2         80                     10

, чтобы внешний запрос больше не путался. Обратите внимание, что вам нужны только псевдонимы в первой ветви объединения (обычно , в любом случае ) - их не повреждает во всех ветвях, они просто игнорируются, но это немного экономит набрав, если вы создаете это вручную. Фактические псевдонимы также не имеют значения в этом случае, они просто должны быть уникальными; в частности, они не должны совпадать со столбцами, в которые вы вставляете, - но если они это сделают, вам будет проще следить за ними.

Если вы сделаете это так, как @Littlefoot показал, что у вас нет промежуточного результата установите select, чтобы производные имена не нужно было оценивать (если можно сказать, что они вообще существуют), поэтому двусмысленность не видна - она ​​чисто позиционная.

4 голосов
/ 07 февраля 2020

Удалить select * from ((и завершающий )).

INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
   SELECT 'FR3158-73-1', 82, 82 FROM DUAL
           UNION ALL
           SELECT 'FR3158-76-2', 80, 10 FROM DUAL

[РЕДАКТИРОВАТЬ, после комментария, что он все еще не работает]

Ну, это работает , по крайней мере, в моем 11gXE:

SQL> select * From v$version where rownum = 1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

SQL> CREATE TABLE sample
  2  (
  3    ID                      NUMBER,
  4    HOST                    VARCHAR2(15 BYTE),
  5    TOTAL_PING              INTEGER,
  6    TOTAL_UNAVAILABLE_PING  INTEGER,
  7    ADDED_ON                TIMESTAMP(6)          DEFAULT systimestamp
  8  );

Table created.

SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
  2     SELECT 'FR3158-73-1', 82, 82 FROM DUAL
  3             UNION ALL
  4             SELECT 'FR3158-76-2', 80, 10 FROM DUAL;

2 rows created.

Нет ошибки на 12 c либо:

SQL> select * from v$version where rownum = 1;

BANNER                                                                               CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production              0

SQL> CREATE TABLE sample
  2  (
  3    ID                      NUMBER,
  4    HOST                    VARCHAR2(15 BYTE),
  5    TOTAL_PING              INTEGER,
  6    TOTAL_UNAVAILABLE_PING  INTEGER,
  7    ADDED_ON                TIMESTAMP(6)          DEFAULT systimestamp
  8  );

Table created.

SQL> INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
  2     SELECT 'FR3158-73-1', 82, 82 FROM DUAL
  3             UNION ALL
  4             SELECT 'FR3158-76-2', 80, 10 FROM DUAL;

2 rows created.

SQL>

Теперь, пожалуйста, докажите, что он не работает в вашей базе данных.

0 голосов
/ 07 февраля 2020

Попробуйте назвать столбцы:

    INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING)
       SELECT 'FR3158-73-1' as host, 82 as total_ping, 82 as total_UNAVAILABLE_PING FROM DUAL
          UNION ALL
       SELECT 'FR3158-76-2' as host, 80 as total_ping, 10 as total_UNAVAILABLE_PING FROM DUAL
;

Но лучший способ:

    INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-73-1',82,82);
    INSERT INTO sample (HOST, TOTAL_PING, TOTAL_UNAVAILABLE_PING) values ('FR3158-76-2',80,10);

, вы избегаете подзапроса. Если у вас есть много данных для вставки в базу данных, рассмотрите SQL* Загрузчик и загрузка из текстового файла. https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sutil/oracle-sql-loader-concepts.html#GUID -DD843EE2-1FAB-4E72-A115-21D97A501E CC

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...