ORA-00907 — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite

Пытаясь сделать эту таблицу, получая ORA-00907: missing right parenthesis , Определение: CREATE TABLE “crawler” ( “id” NUMBER(10,0) NOT NULL ENABLE…

Причина:

Были введены левые скобки без закрытия правыми скобками или в скобках была заключена дополнительная информация. Все скобки должны вводится парами.

4 ответов

Я не эксперт в oracle, но вы можете указать (10) на salary int(10) NOT NULL?

1: у вас должна быть таблица под названием “test” с двумя столбцами, id и testdata. (Это просто глупый быстрый пример, поэтому я не буду утруждать себя указанием каких-либо ограничений на id.)

create table test (id number, testdata varchar2(255));

2: Далее мы создадим последовательность для использования id-номеров в нашей тестовой таблице.

create sequence test_seq start with 1 increment by 1 nomaxvalue;

вы можете изменить “начать с 1” на любое число, с которого хотите начать (например, если у вас уже есть 213 записей в таблице, и вы хотите начать использовать это для своей 214-й записи, замените на “начнем с 214”). По умолчанию используется предложение “increment by 1”, поэтому его можно опустить. Вы также можете заменить его на “increment by n”, если хотите, чтобы он пропускал N-1 чисел между номерами идентификаторов. “Nomaxvalue” говорит ему продолжать увеличивать навсегда, а не сбрасывать в какой-то момент.я (я уверен, что Oracle имеет некоторые ограничения на то, насколько он может быть большим, но я не знаю, что это за предел).

3: Теперь мы готовы создать триггер, который будет автоматически вставлять номер из последовательность в столбце ID.

create trigger test_triggerbefore insert on testfor each row beginselect test_seq.nextval into :new.id from dual;end;/

при создании индекса, встроенного в остальную часть инструкции создания таблицы, попробуйте удалить FOREIGN KEY детали:

CREATE TABLE works(emp_name varchar(20) NOT NULL,comp_name varchar(20) NOT NULL,salary int(10) NOT NULL,emp_name REFERENCES employee(emp_name),comp_name REFERENCES company(comp_name))

см. этот вопрос для получения более подробной информации:

ORA-00907: отсутствует правая скобка

вот смотри есть два различных способа создания таблицы с constriants.

1) создать отдел таблиц( deptno номер (5) первичный ключ, deptname varchar2(30), empno номер (5) ссылки emp (empno));

2) Создайте отдел таблицы( deptno номер(5), deptname varchar2(30), количество empno(5), ограничение pkey_deptno первичный ключ (deptno), ограничение fkey_empno внешний ключ (empno) ссылки Emp (empno));

ORA-00907 Cause

When working with Oracle SQL, all left parenthesis (the “(” character) must be paired with a right parenthesis character (the “)” character).ORA-00907: missing right parenthesis Solution

If there are more left parentheses than right parentheses, then you’ll get this error.

It can also be caused by syntax errors in your CREATE TABLE statement.

Последовательность выполнения триггеров

(Ordered Execution in Triggers)

Начиная с Oracle8, появилась возможность приписать несколько триггеров одного типа одной и той же  таблице — например, два строчных after each row триггера при вставке в одну таблицу. Тип триггеров определяет порядок их выполнения:

  • before statement — перед предложением,
  • before row —  перед строкой,
  • after statement — после предложения,
  • after row — после строки.

Однако, если есть два строчных after-row триггера, T1 и T2, то какой из них сработает первым?

Выполнение триггеров одного и того же типа произвольно или по крайне мере не гарантированно следует шаблону. Является ли это проблемой? Давайте рассмотрим пример таблицы PAYMENTS, показанный ниже:

Name Null? Type—————————— ——– —————————- PAY_ID NUMBER(10) CREDIT_CARD_NO VARCHAR2(16) AMOUNT NUMBER(13,2) PAY_MODE VARCHAR2(1) RISK_RATING VARCHAR2(6) FOLLOW_UP VARCHAR2(1)

Необходимо вычислить рейтинг риска в зависимости от типа платежей и суммы и сохранить его в столбце RISK_RATING. Следующий простой строчный триггер before-update легко справляется с этой задачей:

create or replace trigger tr_pay_risk_ratingbefore updateon paymentsfor each rowbegin dbms_output.put_line (‘This is tr_pay_risk_rating’); if (:new.amount) < 1000 then :new.risk_rating := ‘LOW’; elsif (:new.amount < 10000) then if (:new.pay_mode =’K’) then :new.risk_rating := ‘MEDIUM’; else :new.risk_rating := ‘HIGH’; end if; else :new.risk_rating := ‘HIGH’; end if;end;/

Теперь кто-нибудь добавляет ещё одно требование: некоторые значения, зависящие от столбцов RISK_RATING, PAY_MODE, и др. должны быть в столбце FOLLOW_UP помечены признаком повышения. Триггер необходимо модифицировать, но лучше не трогать существующий код, а создать новый триггер такого же типа (строчный before-update), как показано ниже. (Я поместил в код предложение dbms_output, чтобы показать, как срабатывают триггеры).

create or replace trigger tr_pay_follow_upbefore updateon paymentsfor each rowbegin dbms_output.put_line (‘This is tr_pay_follow_up’); if ( (:new.risk_rating = ‘HIGH’ and :new.pay_mode = ‘C’) or (:new.risk_rating = ‘MEDIUM’ and :new.pay_mode = ‘K’) or (substr(:new.credit_card_no,1,5) = ‘23456’) ) then :new.follow_up := ‘Y’; else :new.follow_up := ‘N’; end if;end;/

Теперь если выполнить обновление таблицы

SQL> get upd_pay 1 update payments set 2 credit_card_no = ‘1234567890123456’, 3 amount = 100000, 4* pay_mode = ‘K’SQL> @upd_pay Это – tr_pay_follow_up Это – tr_pay_risk_rating 1 row updated.SQL> select * from payments; PAY_ID CREDIT_CARD_NO AMOUNT P RISK_R F———- —————- ———- – —— – 1 1234567890123456 100000 C HIGH N

Что же случилось? Столбец risk_rating имеет значение HIGH, а столбец pay_mode – значение ” C”, которые означают, что столбец FOLLOW_UP должен быть ” Y”, а не “N”. Почему? Чтобы ответить на этот вопрос, посмотрите, в каком порядке сработали триггеры: tr_pay_follow_up сработал раньше, чем tr_pay_risk_rating. Последний установил значение столбца как высокий рейтинг. Поэтому, когда заработал первый триггер, он нашёл null (или “N”) в столбце risk_rating и поэтому посчитал, что условие удовлетворяется.

В этом случае порядок выполнения триггеров очень важен. Если tr_pay_risk_rating не сработает раньше второго, корректные значения не будут установлены, а то, что установится, будет неверной реализацией требований. Единственной простой возможностью была бы замена всей логики на один код и выполнение её в нужном порядке.

В Oracle Database 11g можно в скрипте создания триггера указать выражение, которое устанавливает порядок выполнения триггеров. Вот верхняя часть триггера, включающая это выражение:

create or replace trigger tr_pay_follow_upbefore updateon paymentsfor each row
follows tr_pay_risk_rating
begin… и так далее … SQL> @upd_payThis is tr_pay_risk_ratingThis is tr_pay_follow_up 1 row updated. SQL> select * from payments; PAY_ID CREDIT_CARD_NO AMOUNT P RISK_R F———- —————- ———- – —— – 1 1234567890123456 100000 C HIGH Y 1 row selected.

Как и ожидалось, столбец заполнен корректно. Обратите внимание на  корректный порядок триггеров, подтверждающий, что выражение работает.

3 ответа

Лучший ответ

Ваши столбцы no.of во вставке не соответствуют столбцам no.of в поле значений. Попробуй это..

INSERT INTO TABLE_B (car_id, user, book, msdin)select 11, user, book, msdin from TABLE_A ;

prabhat mishra 30 Окт 2017 в 10:52

Возможно, вам нужен оператор INSERT SELECT

INSERT INTO TABLE_B (car_id, user, book, msdin)select 11, user, book, msdin from TABLE_A;

Количество значений и их типы данных, возвращаемые SELECT, должны соответствовать атрибутам таблицы за INSERT. Невозможно использовать подвыбор после VALUES в INSERT при его попытке.

1

Radim Bača 30 Окт 2017 в 09:16

Если ваш TABLE_A имеет только 1 запись, вам нужно будет сделать следующее:

INSERT INTO TABLE_B (car_id, user, book, msdin)values (11, (select user from TABLE_A), (select book from TABLE_A), (select msdin from TABLE_A),);

-2

Sudipta Mondal 30 Окт 2017 в 09:09

47011368

Когда выполнять нечего, выполняем CONTINUE

When Nothing to Do, CONTINUE

Наряду со всеми своими возможностями,  до настоящего времени в PL/SQL была упущена одна важная часть грамматики: как показать, что ничего делать не надо, а надо перейти в конец цикла и продолжить его выполнение.

В Oracle Database 11g в PL/SQL есть новая конструкция CONTINUE, которая используется в цикле. Это предложение перемещает логику в конец цикла, а затем в начало цикла. Вот небольшой пример, который показывает, как управление передаётся на конец цикла, когда счётчик не кратен 10.

begin for ctr in 1..100 loop continue when mod(ctr,10) != 0; dbms_output.put_line (‘ctr=’||ctr); end loop;end;/

Результат:

ctr=10ctr=20ctr=30… и так далее …

Другой вариант CONTINUE – это использование Loop Name (именованный цикл).

begin <<OuterLoop>> for outer in 1..10 loop dbms_output.put_line (‘-> outer=’||outer); for inner in 1..10 loop continue OuterLoop when mod(inner,3) = 0; dbms_output.put_line (‘..-> inner=’||inner); end loop; end loop;end;/

Результат:

-> outer=1..-> inner=1..-> inner=2-> outer=2..-> inner=1..-> inner=2-> outer=3..-> inner=1..-> inner=2… и так далее …

Вместо применения предопределённой конструкции, такой как mod(inner,3), можно использовать функцию, которая выполняет некоторое вычисление.

begin <<OuterLoop>> for outer in 1..10 loop dbms_output.put_line (‘-> outer=’||outer); for inner in 1..10 loop continue OuterLoop when (myfunc = 1); dbms_output.put_line (‘..-> inner=’||inner); end loop; end loop;end;/

Излишне говорить, что эту конструкцию можно использовать только внутри цикла, где она имеет смысл. Если попытаться использовать её снаружи цикла, то появится ошибка компиляции.

Прямые последовательности

(Straight Sequences)

Если ранее в PL/SQL-программе  использовалась последовательность, вплоть до этого релиза нужно было использовать конструкцию типа SELECT <последовательность>.NEXTVAL INTO <название_переменной> FROM DUAL.

declare trans_id number(10);begin select myseq.nextval into trans_id from dual;end;

Больше это не нужно. Вы можете непосредственно присвоить переменной следующее значение последовательности:

declare trans_id number(10);begin trans_id := myseq.nextval;end;/

Это именно то, что я называю простотой.

Действие:

Убедитесь, что вы имеете парное множество скобок, затем выполните выражение снова.

Другие решения

Других решений пока нет …

27.08.2009

ora-904 ora-907 при использовании коррелированных подзапросов

При использовании коррелированных подзапросов, т.е. подзапросов, результаты которых используются для каждой строки основного запроса — «a correlated subquery is evaluated once for each row», могут встречаются ошибки, неточно объясняющие, что делается неправильно

ora-904 «%s: invalid identifier»

ora-907 «missing right parenthesis»

Первая ошибка ora-904 в случае correlated subquery при отсутствии синтаксических ошибок сообщает об использовании более, чем одного уровня глубины вложенности (N-th level sub-query):

что не поддерживается Oracle (до версии 11.1.0.7 включительно) и стандартом SQL: ANSI SQL has table references (correlation names) scoped to just one level deep. Это пишет вице-президент Oracle T.Kyte, отвечая на соответствующий вопрос «Is there some sort of nesting limit for correlated subqueries?», т.е. информация официальная, из первых рук, пример оттуда же. В документации Oracle, начиная с 10.1, пишется иначе:

Oracle performs a correlated subquery when a nested subquery references a column from a table referred to a parent statement any number of levels above the subquery

— но, это, видимо, долгосрочные планы Oracle.

ora-907

тут проблема старая и известная: запрет на использование ORDER BY в подзапросах, описанная в документации Oracle 7 (в документации следующих версий уже не упоминается — видимо, тоже есть планы по исправлению):

The ORDER BY clause cannot appear in subqueries within other statements.

По вышеупомянутой ссылке на сайте asktom.oracle.com можно найти пример замены конструкции с ORDER BY типа:

на аналитическую функцию типа :

для одновременного понижения уровня вложенности подзапроса (correlated query level deep) до 1 и устранения проблемы с ORDER BY в подзапросе — конструкция dense_rank first ORDER BY допускается Oracle.

Необходимо выбрать список значений Item_ID с самой поздней (максимальной) датой, но при выполнении выдаётся ошибка ORA-00907: missing right parenthesis. Если переводить дословно, то она указывает на несоответствие количества скобок. Подскажите, что может быть не так?

Сам фрагмент выбора максимальной даты работает:

photo.jpg

Принудительная Замена Типов. (Только Release 11gR2)

Forced Replacement of Types . (Release R2 Only )

Если вы используете типы, вы, естественно, знаете, насколько это мощный механизм. Можно определить свой собственный тип данных, который может быть составным объектом из различных других типов данных, или из записей, собранных в группу связанных частей данных, или же соответствовать полной строке таблицы. Вот пример типа TY_TRANS, который определяет элементы транзакции:

create or replace type ty_transas object( trans_id number(2), trans_amt number(10))/

Затем, можно создать тип, который содержит данные о продажах. Так как у каждой продаже соответствует транзакция, можно определить столбец типа ty_trans, показанный ниже:

create or replace type ty_salesas object( sales_id number(2), trans_rec ty_trans)/

Как только вы таким способом определяете структуры, TY_SALES становится зависимым от TY_TRANS. Можно подтвердить это, обратившись к представлению  USER_DEPENDENCIES:

SQL> select referenced_name, dependency_type 2 from user_dependencies 3 where name = ‘TY_SALES’ 4 /REFERENCED_NAME DEPE——————— —-STANDARD HARDTY_TRANS HARD

Это показывает, что у TY_SALES есть “твердая” (“hard”) зависимость от типа TY_TRANS.

Теперь давайте посмотрим с общей точки зрения. Что будет, если вы сделали ошибку в определении типов и определили неправильную точность атрибута или же просто захотели изменить заданную точность в связи с бизнес-потребностями? Ну, это –  не проблема, просто воспользуйтесь предложением  CREATE OR REPLACE, чтобы воссоздать этот тип:

create or replace type ty_salesas object( sales_id number(3), trans_rec ty_trans)/

Этим был пересоздан тип с атрибутом sales_id  number(3) вместо number(2), как было ранее. Если эта работа была успешна выполнена для типа ty_sales, можно ли сделать то же самое для ty_trans?

SQL> create or replace type ty_trans 2 as object 3 ( 4 trans_id number (4), 5 trans_amt number 6 ) 7 /create or replace type ty_trans*ERROR at line 1:ORA-02303: cannot drop or replace a type with type or table dependents[ОШИБКА в строке 1:нельзя удалить или заменить тип с табличными или типовыми зависимостями]

Сообщение об ошибке говорит именно об этом – невозможно изменить этот тип, так как он  зависим  от представления user_dependencies, как мы видели ранее. Это – вид отношений отцов и детей (parent-child relationship) между типами. Если есть по крайней мере один дочерний элемент, невозможно удалить (drop) родителя. Каковы возможности для изменения определения “родительского” типа (“parent” type definition)?

До Oracle Database 11g Release 2 единственной возможностью изменить такой тип была фраза  MODIFY ATTRIBUTE  в операторе ALTER TYPE, которая была дорогим и потенциально подверженный ошибкам вариантом. В Release 2 есть очень удобная фраза FORCE, чтобы заменить тип насильственно. Используя её, мы можем изменить тип TY_TRANS следующим образом:

create or replace type ty_transforceas object( trans_id number (4), trans_amt number)/

Это предложение выполнится успешно, и тип будет пересоздан вследствие фразы FORCE, показанной  жирным шрифтом выше. Поэтому, когда вы развертываете приложения, эта возможность очень удобна поскольку не нужно волноваться о том, изменились ли некоторые  атрибуты. А  о полной замене типа скорее позаботится само определение типа, которое изменено или нет.

Рейтинг
( 1 оценка, среднее 5 из 5 )
Загрузка ...