2015-04-04 2 views
3

Я новичок в oracle, исходя из MySQL, и я пытаюсь получить автоинкремент для работы в Oracle с последовательностью и триггером, чтобы он увеличивал мое поле на один , каждый раз, когда я делаю вставку.Автоинкремент в oracle с seq и trigger - invalid sql statement

CREATE SEQUENCE proposals_seq MINVALUE 1 
START WITH 1 INCREMENT BY 1 CACHE 10; 

CREATE OR REPLACE TRIGGER proposals_before_insert 
BEFORE INSERT 
    ON proposals 
    FOR EACH ROW 
BEGIN 
    SELECT proposals_seq.nextval INTO :new.proposal_id FROM dual; 
END; 

Но когда я бегу сценарий, я получаю ошибку:

Error code 900, SQL state 42000: ORA-00900: invalid SQL statement 

Если я удалить ";" после оператора выбора, я не получаю сообщение об ошибке, пока я пытаюсь вставить данные в таблицу, то я получаю эту ошибку:

INSERT INTO proposals (target_audience, line_of_business, activity_description, cost, comments, objectives_and_results) 
    VALUES ('test', 'test', 'test', 15, 'test', 'test'); 

Error code 4098, SQL state 42000: ORA-04098: trigger 'PROPOSALS_BEFORE_INSERT' is invalid and failed re-validation 

Я использую эту версию Oracle: Oracle Database 11g Enterprise Edition Release 11.2. 0.1.0 - 64-разрядные Производство

Все статьи, которые я нашел об этом, кажется, делает это так, и ответы здесь как хорошо: How to create id with AUTO_INCREMENT on Oracle?

Может ли это быть из-за моей версии Oracle? Есть ли другой способ для меня автоинкремент? Или мне придется увеличивать вручную с помощью последовательности в моем sql?

Моя таблица выглядит следующим образом:

CREATE TABLE proposals (
    proposal_id INT NOT NULL, 
    target_audience VARCHAR2(50) NOT NULL, 
    line_of_business VARCHAR2(50), 
    activity_description VARCHAR2(250) NOT NULL, 
    cost DECIMAL(19, 4) NOT NULL, 
    comments VARCHAR2(250), 
    objectives_and_results VARCHAR2(250), 
    PRIMARY KEY (proposal_id) 
); 
+0

Вам не нужно создавать триггер. Просто добавьте nextval вашей последовательности прямо в вашу команду вставки, например, как «вставить в предложения (предложение_ид, ....)» (предложения_seq.nextval, ...) ' –

+2

Я бы хотел избежать этого, так что он всегда согласован , –

+0

Возможно ли, что у вас нет процедурной опции? http://www.dba-oracle.com/sf_ora_00900_invalid_sql_statement.htm - Или, может быть, вы пытаетесь выполнить вышеуказанное в инструменте, который не распознает PL/SQL? http://stackoverflow.com/questions/14868229/how-to-install-procedural-option-in-oracle-11gr2 –

ответ

4

Я подозреваю, что проблема заключается в том, что ваш клиентский инструмент считывает каждую точку с запятой в качестве конца команды, вызывая неверный перевод на сервер кода PL/SQL (который требует точки с запятой в качестве терминаторов операторов).

Когда вы удаляете точку с запятой, оператор корректно отправляется на сервер, но вы получаете недопустимый объект, потому что PL/SQL неверен.

Я продублировал вашу проблему на SQL Fiddle. Тогда я изменяю заявление терминатор / вместо ; и изменил код, чтобы использовать слеш для выполнения каждого оператора, и она работала без ошибок:

CREATE TABLE proposals (
    proposal_id INT NOT NULL, 
    target_audience VARCHAR2(50) NOT NULL, 
    line_of_business VARCHAR2(50), 
    activity_description VARCHAR2(250) NOT NULL, 
    cost NUMBER(19, 4), 
    comments VARCHAR2(250), 
    objectives_and_results VARCHAR2(250), 
    PRIMARY KEY (proposal_id) 
) 
/

CREATE SEQUENCE proposals_seq MINVALUE 1 
START WITH 1 INCREMENT BY 1 CACHE 10 
/

CREATE OR REPLACE TRIGGER proposals_before_insert 
BEFORE INSERT ON proposals FOR EACH ROW 
BEGIN 
    select proposals_seq.nextval into :new.proposal_id from dual; 
END; 
/
+1

Да, это должно быть. Особенно, если OP находится на SQL * Plus, важно помнить, что косые черты между операторами DDL имеют решающее значение (http://stackoverflow.com/a/10207695/905488). SQLDeveloper гораздо более снисходителен в этом отношении. –

-1

Это код, я использую, адаптированный к вашему столу. Он будет работать на любой версии Oracle, но не воспользоваться новой функциональностью в 12, чтобы установить последовательность в качестве автоматического приращения идентификатора

CREATE OR REPLACE TRIGGER your_schema.proposal_Id_TRG BEFORE INSERT ON your_schema.proposal 
FOR EACH ROW 
BEGIN 
    if inserting and :new.Proposal_Id is NULL then 
    SELECT your_schema.proposal_Id_SEQ.nextval into :new.Proposal_Id FROM DUAL; 
    end if; 

END; 
/

и использование является

INSERT INTO proposals (proposal_id,target_audience, line_of_business, activity_description, cost, comments, objectives_and_results) 
    VALUES (null,'test', 'test', 'test', 15, 'test', 'test'); 

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

-1

Я создал ПОСЛЕДОВАТЕЛЬНОСТЬ и Trigger в Oracle для моего стола.

моя сущность:

@Entity 
@Table(name = "TBL_AUTHENTICATE") 
public class UserSession implements Serializable { 
    @Id 
    @Column(name = "SESSIONID", nullable = false, length = 12) 
    private Long sessionId; 

    @Column(name = "USER_ID", nullable = false, length = 10) 
    private int user_id; 

    @Column(name = "TIME_TO_LIVE", nullable = false) 
    private Date time_to_live; 

:-D
Я пытаюсь вставить данные в пределах этой таблицы и установить SESSIONID с моим сгенерированным значением и, наконец, я понимаю проблему. Это моя ошибка.

then I drom Последовательность и триггер из таблицы.
Моя проблема решена.