sql >> Database teknologi >  >> RDS >> Oracle

Oracle - markøren, der bruger dbms_utility.exec_ddl_statement, udføres ikke korrekt

DBMS_UTILITY.EXEC_DDL_STATEMENT kører kun DDL pålideligt. Hvis du prøver at køre det med en PL/SQL-blok, vil det lydløst fejle og ikke køre noget.

Dette kan demonstreres ved at køre en PL/SQL-blok, der åbenbart skulle mislykkes. Koden nedenfor skal generer ORA-01476: divisor is equal to zero . Men i stedet gør det ingenting.

begin
    [email protected](
        q'[declare v_test number; begin v_test := 1/0; end;]'
    );
end;
/

Brug en midlertidig procedure til at køre en PL/SQL-blok eksternt. Opret proceduren med DBMS_UTILITY.EXEC_DDL_STATEMENT og kald det derefter med indbygget dynamisk SQL.

begin
    [email protected](
        q'[
            create or replace procedure test_procedure
            is
                v_test number;
            begin
                v_test := 1/0;
            end;
        ]'
    );
    execute immediate 'begin [email protected]; end;';
end;
/

RESULTS:

ORA-01476: divisor is equal to zero
ORA-06512: at "JHELLER.TEST_PROCEDURE", line 5
ORA-06512: at line 1
ORA-06512: at line 12

Jeg tror, ​​at denne adfærd er en fejl. Oracle burde kaste en fejl i stedet for simpelthen ikke at gøre noget.

Velkommen til sammenkædningshelvede. Strenge bliver rodet, når de er indlejret 4 niveauer dybt. Men der er et par ting, du kan gøre for at gøre livet lettere:

  1. Brug indlejrede alternative citeringsmekanismer. For eksempel q'[ ... ]' , inde i en q'< ... >' osv.
  2. Brug strenge med flere linjer. Der er ingen grund til at sammenkæde flere linjer, bare brug en enkelt streng.
  3. Brug ekstra mellemrum til at hjælpe med at identificere starten og slutningen af ​​strenge. Når tingene bliver så vanvittige, er det værd at sætte en streng-afgrænsning på en linje helt af sig selv, så alt er nemt at stille op.
  4. Brug REPLACE i stedet for sammenkædning.

Jeg omformaterede en del af din kode ved hjælp af disse tips. Stackoverflow forstår ikke den alternative citeringsmekanisme, men strengene burde se bedre ud i en god Oracle SQL-editor.

declare
    v_db_name varchar2(30) := 'myself';
    sql_update varchar2(32767);
begin
    execute immediate replace(
    q'[
        begin
            [email protected]#DB_NAME#
            (
                q'<
                    create or replace procedure cw_drop_table is
                        sql_drop varchar2(2000);
                    begin
                        sql_drop :=
                        q'{
                            BEGIN
                                EXECUTE IMMEDIATE 'DROP TABLE iSecurity2_dupes_bak';
                            EXCEPTION WHEN OTHERS THEN
                                IF SQLCODE != -942 THEN
                                    NULL;
                                END IF;
                            END;
                        }';
                        execute immediate sql_drop;
                    end;
                >'
            );
            execute immediate 'begin [email protected]#DB_NAME#; end;';
        end;
    ]', '#DB_NAME#', v_db_name);

    sql_update := 'create table iSecurity2_dupes_bak as select * from iSecurity2';
    execute immediate 'begin [email protected]'||v_db_name||
        '(:sql_update);  end;' using sql_update;
    commit;
end;
/



  1. Opret forbindelse til MySql db over SSH i Netbeans

  2. Generer unikt ID

  3. Udfyld multidimensionel array

  4. Hent data baseret på måned af et kvartal i sql