2013-02-14 2 views
0

Я генерируя процедуру для проверки всех вопросов, данных, как дублей в базе данных tables.So формат как таковой поясняются ниже:Как импортировать запрос из файла в процедуру

CREATE TABLE <test_table> --table i created to save the procedure test results 
(
RUN_ID number, 
QUERY_ID NUMBER, 
QUERY_NAME VARCHAR(1000), 
QUERY_STATUS  VARCHAR(10), 
MAIN_TABLE_NAME VARCHAR(500), 
EXP_RESULT VARCHAR(4000), 
ACT_RESULT VARCHAR(4000), 
RUN_ON_DT DATE, 
TEST_LEVEL_GIVEN NUMBER, 
START_TIME_WID NUMBER, 
END_TIME_WID NUMBER, 
TEST_QUERY VARCHAR(4000), 
QUERY_DESC VARCHAR(4000), 
Comments VARCHAR(4000) 
) 




create or replace 
    PROCEDURE PROC_TESTING (TEST_LEVEL IN NUMBER DEFAULT 0 , START_WID IN NUMBER DEFAULT 0, END_WID NUMBER DEFAULT 0) IS 
    --TEST_LEVEL=0 IS TO RUN ALL QUERIES : FULL PROCEDURE 
    --TEST_LEVEL=1 IS FOR BASIC QUERIES 
    --TEST_LEVEL=2 IS FOR DIMENSION QUERIES 
    --TEST_LEVEL=3 IS FOR FACT QUERIES 
    --TEST_LEVEL=4 IS FOR .... QUERIES 
    --TEST_LEVEL=5 IS FOR .... QUERIES 

V_RUN_ID NUMBER; 
V_QUERY_ID NUMBER; 
V_QUERY_NAME VARCHAR(1000); 
V_QUERY_STATUS  VARCHAR(10); 
V_MAIN_TABLE_NAME VARCHAR(500); 
V_EXP_RESULT VARCHAR(4000); 
V_ACT_RESULT VARCHAR(4000); 
V_RUN_ON_DT DATE; 
V_TEST_QUERY VARCHAR(4000); 
V_QUERY_DESC VARCHAR(4000); 
V_COMMENTS VARCHAR(4000); 



BEGIN 

DBMS_OUTPUT.PUT_LINE('STARTING THE TESTING PROC ON ' || SYSDATE); 

SELECT RUN_ID.NEXTVAL INTO V_RUN_ID FROM DUAL; 

SELECT SYSDATE INTO V_RUN_ON_DT FROM DUAL; 

IF TEST_LEVEL<>1 and TEST_LEVEL<>2 and TEST_LEVEL<>0 
Then 
    DBMS_OUTPUT.PUT_LINE('Conditions not met' || SYSDATE); 
    return; 
end if; 



IF TEST_LEVEL=1 or TEST_LEVEL=2 or TEST_LEVEL=0 
Then 
    V_QUERY_ID:=1; 
    V_QUERY_NAME:='Duplicates check'; 
    V_MAIN_TABLE_NAME:='<table_to_be_tested>'; 
    V_QUERY_DESC:='checking for duplicates'; 

    -- Expected results 
    V_EXP_RESULT := 0; 
    -- Actual results 

    select count(*) into V_ACT_RESULT 
    from (select id1 
         , id2 
         , EFFECTIVE_FROM_DT 
         , EFFECTIVE_TO_DT 
         , update_dt  
         , row_number() over (partition by 
         id1 
         , id2 
         , EFFECTIVE_FROM_DT 
         , EFFECTIVE_TO_DT 
      order by integration_id) as occurrence 
      from <table_to_be_tested>) x 
    where occurrence > 1; 

    IF V_EXP_RESULT = V_ACT_RESULT THEN 
    V_QUERY_STATUS:='PASS'; 
    ELSE 
    V_QUERY_STATUS:='FAIL'; 
    END IF; 

END IF; 



Insert into <test_table>  --going to store all above explained values into this table 
(
RUN_ID , 
QUERY_ID , 
QUERY_NAME , 
QUERY_STATUS , 
MAIN_TABLE_NAME , 
EXP_RESULT, 
ACT_RESULT , 
RUN_ON_DT, 
TEST_LEVEL_GIVEN, 
START_TIME_WID, 
END_TIME_WID, 
TEST_QUERY , 
QUERY_DESC, 
Comments) 
values 
(
V_RUN_ID , 
V_QUERY_ID , 
V_QUERY_NAME, 
V_QUERY_STATUS , 
V_MAIN_TABLE_NAME , 
V_EXP_RESULT , 
V_ACT_RESULT , 
V_RUN_ON_DT , 
TEST_LEVEL, 
START_WID, 
END_WID, 
V_TEST_QUERY , 
V_QUERY_DESC , 
V_COMMENTS); 


END; 

Теперь у меня есть два вопроса я сделали все, кроме сохранения значений TEST_LEVEL, START_WID, END_WID, в которых я прокомментировал процедуру, потому что, используя их, я получал ошибку компилятора. Вопрос 1: -Как хранить TEST_LEVEL, START_WID, END_WID в (Ответил с помощью ответа @Swapna.) Вопрос 2: -Я буду запускать несколько запросов на разных таблицах и хранить их в V_ACT_RESULT, поэтому я подумал, это способ сохранить все запросы в каком-либо текстовом файле, а затем просто импортировать их здесь с помощью какого-либо скрипта. Если кто-нибудь знает, как это сделать, пожалуйста, уточните.

ответ

1

Для операторов, как ваша ... Выберите из < < table_to_be_tested >> Isert в < < table_to_be_tested >> .... вам необходимо использовать динамический SQL, например, ВЫПОЛНИТЕ НЕМЕДЛЕННЫЙ ИЛИ ЗАВЕРШЕННЫЙ КУРСОР. Вот общий пример оператора sql, созданного «на лету» на основе таблицы Oracle scott.emp. Вы делаете то же самое для вставки/обновления ...:

DECLARE 
    PROCEDURE get_total(p_tab_name VARCHAR2:= 'scott.emp' 
        , p_column_name VARCHAR2:= 'JOB' 
        , p_list VARCHAR2:= '''MANAGER'', ''CLERK''') 
IS 
    v_sql   VARCHAR2(200); 
    cnt    NUMBER:= 0; 
BEGIN 
dbms_output.put_line(p_list); 
    v_sql:= 'SELECT count(*) total FROM '|| p_tab_name || 
      ' WHERE '||p_column_name||' IN ('||p_list||')'; 
    EXECUTE IMMEDIATE v_sql INTO cnt; 
    dbms_output.put_line(cnt); 
END; 
BEGIN 
get_total; 
END; 
/

Output: 

'MANAGER', 'CLERK' 
7 

Oracle документы - вы можете найти больше на эту тему, используя документы Oracle, поиск ...: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/executeimmediate_statement.htm#LNPLS01317

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

+0

Я не эксперт по sql, поэтому вы можете разработать в небольшом блоке кода, как хранить эти три в таблице, которую я испробовал EXECUTE IMMEDIATE, и получил ошибку компилятора. – Auguster

+0

@Auguster - Надеюсь, пример помогает. Вы считаете, что запрос нужно преобразовать в динамический запрос, как в моем примере. То же самое с вашей вставкой. Объявите другую переменную и создайте свою вставку, затем используйте execute немедленно: EXECUTE IMMEDIATE 'INSERT INTO' || table_name || ' ЗНАЧЕНИЯ...(...)'; – Art

1

START_WID и END_WID определяется как номер в параметре ввода процедуры и его вставка в поля даты. Это может быть одной из причин, по которым вы получаете ошибку компиляции. Это поможет, если вы поделитесь также ошибкой.

+0

Это было очень полезно, он решил мой первый вопрос. – Auguster

+0

Теперь, если вы можете помочь со вторым вопросом. Все предложения тоже приветствуются. – Auguster

+0

Это всего лишь предложение для вашей второй проблемы, возможно, не лучший подход. Вы можете сохранить все имена таблиц и запросы, которые вы хотите выполнить против них в таблице, и пропустить их через них и сделать то, что вы делаете прямо сейчас, чтобы вставить в таблицу результатов теста. Я не думаю, что вам нужно записать его в файл и импортировать обратно. –

Смежные вопросы