Closed reiniero closed 10 years ago
I have noticed that FlameRobin is generating empty stored procedures when scripting database to overcome this issue, then at last update them by the actual procedure body. Actually I haven't used FireBird stored procedures, and I don't like to use stored procedures in my applications, so that I can't do any help in this area
On 01/05/2014 20:00, Motaz Abdel Azeem wrote:
I have noticed that FlameRobin is generating empty stored procedures when scripting database to overcome this issue, then at last update them by the actual procedure body. Yes, and FlameRobin's support for dependencies still isn't ok (at least their views still don't sort correctly).
Actually I haven't used FireBird stored procedures, and I don't like to use stored procedures in my applications, so that I can't do any help in this area No problem, I'll probably figure it out ;)
Strored procedures are Evil :) http://c2.com/cgi/wiki?StoredProceduresAreEvil
On 01/05/2014 20:13, Motaz Abdel Azeem wrote:
Strored procedures are Evil: http://c2.com/cgi/wiki?StoredProceduresAreEvil
Regardless of my personal opinion about stored procedures (which varies between love and hate, depending on the lunar cycle) ;) it would be nice if TurboBird could at least properly script & restore the standard sample database provided by Firebird, don't you think ;)
That said, I suspect a lot of the dependency trouble I'm seeing in SPs will also pop up in views... which you perhaps also don't use (but I do) ;)
Yes, you are right, we should be neutral, and let the user decide. for views, yes I didn't use also, but I have nothing against it this time :) one of "Views" inventors is the president of my university (Sudan university) he is a very famous here in Sudan.
Actually I have concentrated on things that I need in FireBird in my various commercial projects, and I'm almost done with it, now it covers most of my needs, and it is time to other developers to participate, so that you have appear just in right time.
Ok ;) Stored procedures sorting internally (i.e. stored procs depending on other stored procs) has been committed in e4c666421c3ed8e80a5bf9aa23b546d18512e25a. Future enhancement could be splitting out generating stored proc header and body as motaz indicated, and putting views in between (which may depend on stored procs). FYI, views sorting (internally) has been implemented in commit 19f5e8a3ba3eb33b493a0df7f4149197b28e7146
Will reopen this bug (or another one) if further sorting/splitting out needs to occur.
When scripting the FB 2.5 Employee database, dependency order between stored procedures is not followed; instead SPs are created alphabetically
Stored procedure section of script demonstrating the problem: procedure ALL_LANGS needs procedure show_langs which has not been created yet at that time.
-- Stored Procedures
SET TERM ^ ; CREATE Procedure ADD_EMP_PROJ ( EMP_NO SMALLINT, PROJ_ID CHAR(5) )
AS BEGIN BEGIN INSERT INTO employee_project (emp_no, proj_id) VALUES (:emp_no, :proj_id); WHEN SQLCODE -530 DO EXCEPTION unknown_emp_id; END SUSPEND; END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure ALL_LANGS RETURNS ( CODE VARCHAR(5), GRADE VARCHAR(5), COUNTRY VARCHAR(15), LANG VARCHAR(15) )
AS BEGIN FOR SELECT job_code, job_grade, job_country FROM job INTO :code, :grade, :country
^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure DELETE_EMPLOYEE ( EMP_NUM INTEGER )
AS DECLARE VARIABLE any_sales INTEGER; BEGIN any_sales = 0;
END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure DEPT_BUDGET ( DNO CHAR(3) )
RETURNS ( TOT Decimal(18,2) )
AS DECLARE VARIABLE sumb DECIMAL(12, 2); DECLARE VARIABLE rdno CHAR(3); DECLARE VARIABLE cnt INTEGER; BEGIN tot = 0;
END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure GET_EMP_PROJ ( EMP_NO SMALLINT )
RETURNS ( PROJ_ID CHAR(5) )
AS BEGIN FOR SELECT proj_id FROM employee_project WHERE emp_no = :emp_no INTO :proj_id DO SUSPEND; END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure MAIL_LABEL ( CUST_NO INTEGER )
RETURNS ( LINE1 CHAR(40), LINE2 CHAR(40), LINE3 CHAR(40), LINE4 CHAR(40), LINE5 CHAR(40), LINE6 CHAR(40) )
AS DECLARE VARIABLE customer VARCHAR(25); DECLARE VARIABLE first_name VARCHAR(15); DECLARE VARIABLE last_name VARCHAR(20); DECLARE VARIABLE addr1 VARCHAR(30); DECLARE VARIABLE addr2 VARCHAR(30); DECLARE VARIABLE city VARCHAR(25); DECLARE VARIABLE state VARCHAR(15); DECLARE VARIABLE country VARCHAR(15); DECLARE VARIABLE postcode VARCHAR(12); DECLARE VARIABLE cnt INTEGER; BEGIN line1 = ''; line2 = ''; line3 = ''; line4 = ''; line5 = ''; line6 = '';
END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure ORG_CHART RETURNS ( HEAD_DEPT CHAR(25), DEPARTMENT CHAR(25), MNGR_NAME CHAR(20), TITLE CHAR(5), EMP_CNT INTEGER )
AS DECLARE VARIABLE mngr_no INTEGER; DECLARE VARIABLE dno CHAR(3); BEGIN FOR SELECT h.department, d.department, d.mngr_no, d.dept_no FROM department d LEFT OUTER JOIN department h ON d.head_dept = h.dept_no ORDER BY d.dept_no INTO :head_dept, :department, :mngr_no, :dno DO BEGIN IF (:mngr_no IS NULL) THEN BEGIN mngr_name = '--TBH--'; title = ''; END
END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure SHIP_ORDER ( PO_NUM CHAR(8) )
AS DECLARE VARIABLE ord_stat CHAR(7); DECLARE VARIABLE hold_stat CHAR(1); DECLARE VARIABLE cust_no INTEGER; DECLARE VARIABLE any_po CHAR(8); BEGIN SELECT s.order_status, c.on_hold, c.cust_no FROM sales s, customer c WHERE po_number = :po_num AND s.cust_no = c.cust_no INTO :ord_stat, :hold_stat, :cust_no;
END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure SHOW_LANGS ( CODE VARCHAR(5), GRADE SMALLINT, CTY VARCHAR(15) )
RETURNS ( LANGUAGES VARCHAR(15) )
AS DECLARE VARIABLE i INTEGER; BEGIN i = 1; WHILE (i <= 5) DO BEGIN SELECT language_req[:i] FROM joB WHERE ((job_code = :code) AND (job_grade = :grade) AND (job_country = :cty) AND (language_req IS NOT NULL)) INTO :languages; IF (languages = ' ') THEN /* Prints 'NULL' instead of blanks */ languages = 'NULL';
i = i +1; SUSPEND; END END ^ SET TERM ; ^
SET TERM ^ ; CREATE Procedure SUB_TOT_BUDGET ( HEAD_DEPT CHAR(3) )
RETURNS ( TOT_BUDGET Decimal(18,2) , AVG_BUDGET Decimal(18,2) , MIN_BUDGET Decimal(18,2) , MAX_BUDGET Decimal(18,2) )
AS BEGIN SELECT SUM(budget), AVG(budget), MIN(budget), MAX(budget) FROM department WHERE head_dept = :head_dept INTO :tot_budget, :avg_budget, :min_budget, :max_budget; SUSPEND; END ^ SET TERM ; ^
/* Views */
CREATE VIEW "PHONE_LIST" (EMP_NO, FIRST_NAME, LAST_NAME, PHONE_EXT, LOCATION, PHONE_NO) AS SELECT emp_no, first_name, last_name, phone_ext, location, phone_no FROM employee, department WHERE employee.dept_no = department.dept_no ;
-- Triggers
SET TERM ^ ; Create Trigger POST_NEW_ORDER for SALES ACTIVE After Insert Position 0 AS BEGIN POST_EVENT 'new_order'; END ^ SET TERM ; ^
SET TERM ^ ; Create Trigger SAVE_SALARY_CHANGE for EMPLOYEE ACTIVE After Update Position 0 AS BEGIN IF (old.salary <> new.salary) THEN INSERT INTO salary_history (emp_no, change_date, updater_id, old_salary, percent_change) VALUES ( old.emp_no, 'NOW', user, old.salary, (new.salary - old.salary) * 100 / old.salary); END ^ SET TERM ; ^
SET TERM ^ ; Create Trigger SET_CUST_NO for CUSTOMER ACTIVE Before Insert Position 0 AS BEGIN if (new.cust_no is null) then new.cust_no = gen_id(cust_no_gen, 1); END ^ SET TERM ; ^
SET TERM ^ ; Create Trigger SET_EMP_NO for EMPLOYEE ACTIVE Before Insert Position 0 AS BEGIN if (new.emp_no is null) then new.emp_no = gen_id(emp_no_gen, 1); END ^ SET TERM ; ^