2010-04-11 38 views
16

Đối với ứng dụng của tôi sử dụng Oracle 8 DB, tôi đang cung cấp một tập lệnh SQL để thiết lập các công cụ như trình kích hoạt, chuỗi, vv, có thể được sao chép và dán vào SQL * Plus. Tôi muốn kịch bản không dừng lại với một lỗi nếu một chuỗi mà tôi đang cố gắng tạo đã tồn tại. Đối với Trình kích hoạt, điều này có thể dễ dàng được thực hiện bằng cách sử dụng "tạo hoặc thay thế trình kích hoạt ...", nhưng đối với một chuỗi, thao tác này không hoạt động. Tôi cũng đã thử "" nếu không tồn tại hậu quả, sau đó tạo ra trình tự ... "nhưng nó cũng không quá. Có một số thay thế?Có cái gì đó như "nếu không tồn tại tạo chuỗi ..." trong Oracle SQL?

Ngoài ra, nếu điều này là không thể, có cách nào để thực hiện" "không có SQL * Plus hủy kịch bản nếu mysequence không tồn tại

+0

Làm thế nào sự hiện diện của một chức năng autoincrement trong Oracle sẽ giúp giải quyết những gì rõ ràng là một vấn đề quản lý kiểm soát nguồn/cấu hình? – APC

+0

@APC: Xin lỗi, tôi không hiểu. Bạn có thể giải thích chi tiết hơn không? Ý tôi là: tất cả những gì tôi cần cho một cái bàn là một trường tự động. Ví dụ: SQL Server Tôi chỉ xác định cột là một trường tự động, và tôi đã làm xong. Trong Oracle, tôi cần phải tạo một cột số, sau đó là một chuỗi, sau đó một trình kích hoạt để sử dụng chuỗi đó để điền vào cột của tôi. Điều này không có vẻ rất căng thẳng đối với tôi. – Timo

+0

Quan điểm của tôi là, nếu bạn có quản lý lược đồ thích hợp, bạn sẽ không cần phải xử lý sự tồn tại trước của chuỗi bởi vì bạn sẽ chỉ chạy câu lệnh CREATE SEQUENCE đối với cơ sở dữ liệu mà bạn biết rằng chuỗi đó không tồn tại. – APC

Trả lời

7

Nếu bạn chắc chắn kịch bản sẽ luôn luôn chạy theo SQL * Plus, bạn có thể đặt dấu ngoặc những điều khoản SEQUENCE CREATE với một chỉ thị để tiếp tục về lỗi:

WHENEVER SQLERROR CONTINUE 
-- create sequences here, ignoring errors 
WHENEVER SQLERROR EXIT SQL.SQLCODE 

Hãy nhận biết nếu có những sai sót khác (phép vấn đề, thất bại cú pháp, vv) trong các báo cáo tự tạo ra họ sẽ bị bỏ qua

+0

Tốt, tôi không biết về chỉ thị đó. Cảm ơn! – Timo

1

Bạn có thể kiểm tra user_sequence bảng để xem liệu trình tự được tạo ra đã tồn tại hay không

Tương tự như davek 's giải pháp:?. ý tưởng là , trước khi tạo chuỗi bất kỳ, hãy thả chuỗi và tạo chuỗi, tất cả trong SQL động, tạo một hàm và nói khi nào bạn cần tạo 10 chuỗi, hãy để fu nction take care ...

function crt_seq(p_seq_name varchar2) 
return boolean 
begin 
    for i in (select 1 from user_sequence where sequence_name = upper(p_seq_name)) 
    loop 
    ---- Already exists. You can drop and recreate or return false to error out 
    execute immediate 'drop sequence '||p_seq_name; 
    execute immediate 'create sequence '||p_seq_name||' start with 1 increment 
        by 1 nocache'; 
    end loop; 
    return true; 
exception 
when others then 
    return false; 
end; 

Bạn có thể parametrize tất cả các tùy chọn khác và có chức năng phức tạp để tạo chuỗi cho bạn.

+0

Tôi phải thừa nhận Tôi là người mới đến Oracle, tôi thậm chí không biết xác định chức năng đó ở đâu và cách gọi nó từ tập lệnh SQL của tôi, nhưng sách của tôi trên Oracle đã có trên bàn làm việc của tôi, vì vậy câu trả lời của bạn có thể giúp tôi khi tôi có kiến ​​thức :-) Cảm ơn. – Timo

+1

Cảnh báo: Nếu bạn có mã (ví dụ như gói) sử dụng trình tự, điều này sẽ làm mất hiệu lực chúng. Bạn cũng có thể gặp sự cố về khóa nếu các gói đó được sử dụng khi bạn chạy mã này. Oh, và nếu trình tự đã tồn tại và đã được sử dụng, bạn sẽ nhận được các giá trị trùng lặp. –

+0

Ok, cảm ơn. – Timo

11
DECLARE 
    v_dummy NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT 1 
    INTO v_dummy 
    FROM user_sequences 
    WHERE sequence_name = 'MY_SEQUENCE_NAME'; 

    -- if sequence found, do nothing 
EXCEPTION 
    WHEN no_data_found THEN 
    -- sequence not found, create it 
    EXECUTE IMMEDIATE 'create sequence my_sequence_name'; 
END; 
+1

Thử tốt, nhưng ở dạng này, nó sẽ không hoạt động. Bạn có vấn đề chữ thường-chữ thường: Nên là WHERE sequence_name = 'MY_SEQUENCE_NAME'; –

+0

@ammoQ Bây giờ nó đã được sửa chữa, cảm ơn. – jva

+0

Tôi thay đổi tên bảng thành 'user_sequences' – Shawn

4

tôi thích:

DECLARE 
    C NUMBER; 
BEGIN 
    SELECT COUNT(*) INTO C 
    FROM ALL_TRIGGERS 
    WHERE OWNER = 'YOUROWNER' 
    AND TRIGGER_NAME = 'YOURTRIGGER'; 

    IF (C = 0) THEN 
    EXECUTE IMMEDIATE ' 
     CREATE TRIGGER "YOUROWNER"."YOURTRIGGER" 
     blah blah blah your trigger blah blah 
    '; 
    END IF; 
END; 
/
+0

Dễ dàng hơn nhiều khi sử dụng TẠO HOẶC THAY THẾ TRIGGER MyTriggerName TRƯỚC KHI CH INSN TRÊN MyTable ..... – Oscar

0
DECLARE 
    lsSeqName VARCHAR2(32 CHAR) := UPPER('MY_SEQUENCE_NAME'); 
    lnSeqCount NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT count(1) 
    INTO lnSeqCount 
    FROM user_sequences 
    WHERE UPPER(sequence_name) = lsSeqName; 
    -- if sequence not found, create it 
    IF lnSeqCount = 0 THEN 
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || lsSeqName || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER'; 
    END IF; 
END; 
/

HOẶC

-- helper method 
PROCEDURE createSeqIfNotExists (
    isSeqName VARCHAR2 
) IS 
    lnSeqCount NUMBER; 
BEGIN 
    -- try to find sequence in data dictionary 
    SELECT count(1) 
    INTO lnSeqCount 
    FROM user_sequences 
    WHERE UPPER(sequence_name) = UPPER(isSeqName); 
    -- if sequence not found, create it 
    IF lnSeqCount = 0 THEN 
    EXECUTE IMMEDIATE 'CREATE SEQUENCE ' || UPPER(isSeqName) || ' START WITH 1 MINVALUE 1 MAXVALUE 1000000000000000 INCREMENT BY 1 NOCYCLE CACHE 20 NOORDER'; 
    END IF; 
END createSeqIfNotExists; 

-- call method 
BEGIN 
    createSeqIfNotExists('MY_SEQUENCE_NAME'); 
END; 
/
Các vấn đề liên quan