2011-12-13 21 views
5

Tôi hiện đang làm việc để sửa đổi cơ sở dữ liệu Firebird v. 1.5.Đang cập nhật số phát hành giá trị máy phát điện

Cấu trúc cơ sở dữ liệu sẽ được sửa đổi các truy vấn đang chạy từ ứng dụng delphi sử dụng các thành phần cơ sở, vấn đề tôi đang gặp phải là tôi cần chạy nhiều truy vấn, một số trong đó bao gồm tạo trình tạo và cập nhật giá trị của trình tạo vấn đề là tôi cần phải đạt được điều này trong khi vài thắc mắc càng tốt, nhưng có vẻ như (ít nhất là với tôi) rằng điều này không thực sự có thể, những gì tôi đang cố gắng làm là như sau:

/* this command creates a generator to be used for table TABLENAME */ 
CREATE GENERATOR GEN_TABLENAME; 

vì vậy, Tôi đã tạo một trình tạo, bây giờ tôi cần đặt giá trị của nó ở id tối đa hiện tại từ bảng TABLENAME, như sau:

/* one would expect that the following command would work, well it doesn't */ 
SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME); 

Bây giờ, là có bất kỳ workaround cho điều này, hoặc tôi buộc phải:

  • tạo máy phát điện
  • nhận được id max
  • cập nhật giá trị phát

và lặp lại quá trình cho mỗi bảng?

Tôi cũng mong rằng

SELECT 
    SELECT MAX(ID) AS ID_TABLENAME_1 FROM TABLENAME_1, 
    ... 
    SELECT MAX(ID) AS ID_TABLENAME_N FROM TABLENAME_N 

sẽ là một cách giải quyết để có được tối đa của id từ mỗi bảng trong một lệnh, nhưng nó không.

+0

bạn đang sử dụng các thành phần nào? – rstrelba

+0

@rstrelba interbase – ComputerSaysNo

+0

Tôi quan tâm đến tên của các thành phần delphi. TIBDatabase? TIBQuery? TIBDataSet? – rstrelba

Trả lời

6

Tuyên Bố

SET GENERATOR GEN_TABLENAME TO (SELECT MAX(ID) FROM TABLENAME); 

trộn DDL (SET GENERATOR) và DML (SELECT), AFAIK này không thường hỗ trợ và Firebird không hỗ trợ nó cho chắc chắn.

Nếu bạn có thể nâng cấp lên phiên bản Firebird mới nhất, bạn có thể sử dụng EXECUTE BLOCK và/hoặc EXECUTE STATEMENT để thực hiện tất cả "trong một tuyên bố" và phía máy chủ, nhưng với Firebird 1.5 bạn phải giải quyết một chặng đường dài tuyên bố để có được tối đa hiện tại, sau đó một số khác cập nhật trình tạo).

+0

+1 cảm ơn bạn ain, tôi không thể nâng cấp, bởi vì mã cơ sở nó khá lớn và thời gian để kiểm tra tất cả các chức năng bị hạn chế, do đó nâng cấp là ra khỏi câu hỏi. Tôi hy vọng có một giải pháp thanh lịch hơn): – ComputerSaysNo

+0

Tôi nghĩ tôi đã dành đủ thời gian cho câu hỏi này, câu trả lời của bạn gần hơn với câu hỏi của tôi, không may là tôi phải đi theo "cách còn" để giải quyết vấn đề, nghĩa là nhiều truy vấn ..., cảm ơn bạn đã trả lời của bạn (: – ComputerSaysNo

4

Bạn có thể tạo một thủ tục lưu trữ và gọi nó là từ Delphi:

create procedure update_generators 
as 
    declare variable max_id integer; 
    declare variable table_name char(31); 
    declare variable generator_name char(31); 
begin 
    /* assuming generator naming convention GEN_XXX -> table name XXX */ 
    for select 
    trim(g.rdb$generator_name), 
    substring(trim(g.rdb$generator_name) from 5) 
    from rdb$generators g 
    where (coalesce(g.rdb$system_flag, 0) = 0) 
    into 
    :generator_name, 
    :table_name 
    do 
    begin 
    /* assuming that the field name is always ID */ 
    execute statement 'select max(id) from ' || :table_name into :max_id; 
    execute statement 'set generator ' || :generator_name || ' to ' || :max_id; 
    end 
end^ 

Dường như execute statementsupported by Firebird 1.5 rồi. Trong Firebird 2.0 trở lên, bạn cũng có thể quấn mã trong một số execute block và tránh tạo quy trình được lưu trữ.

+0

+1 cảm ơn bạn TOndrej, bạn đã đúng, GEN_TABLENAME là quy ước, nhưng tôi thích một giải pháp đơn giản – ComputerSaysNo

2

Với cách lừa sau bạn có thể để thiết lập giá trị máy phát điện với giá trị tối đa ID của một bảng với một câu lệnh SQL trong Firebird:

SELECT GEN_ID(GEN_TABLENAME, 
    (SELECT MAX(ID) FROM TABLENAME) - GEN_ID(GEN_TABLENAME, 0)) FROM RDB$DATABASE; 

đó làm việc, bởi vì GEN_ID(<GeneratorName>, <increment>) được giá trị máy phát điện và tăng nó bằng cách <increment>. Điều này sẽ làm việc trong Firebird 1.5 cũng như trong các phiên bản mới hơn.

+0

Nếu bạn biết máy phát điện là 0, điều này thậm chí còn đơn giản hơn: 'SELECT GEN_ID (GEN_TABLENAME, (SELECT MAX (ID) TABLENAME)) TỪ RDB $ DATABASE; ' – yonojoy

Các vấn đề liên quan