使用c#代码中的函数执行oracle DDL脚本

时间:2016-08-10 18:04:08

标签: c# sql oracle ddl

我使用Oracle数据库用C#代码编写了一些集成测试。测试项目有一个CreateDatabase.sql,它包含用于在每次测试执行中创建整个数据库的DDL。

当我只有序列和表时,我在";" char中分割这个文件的内容并分别执行每个create语句,但现在我有一些函数,它们的语句包含一些{{1其中有字符,所以我不能再使用这种方法了。

我已查看.NET / Oracle: How to execute a script with DDL statements programmatically个问题,但没有帮助。

1)如果我尝试在单个OracleCommand中执行整个文件内容,由于;字符

,我收到错误ORA-00911: invalid character

2)如果我尝试将文件内容包装在;中,则会收到错误"begin {0} end;"

3)我可以尝试解析SQL文件并将每个语句放在EXECUTE IMMEDIATE中,但这样会更难......

还有其他选择吗?

我使用Oracle.DataAccess版本4.112.3.0来执行命令。

修改 @kevinsky要求一个脚本,这里是一个简化的例子......整个脚本创建了数百个对象......

PLS-00103: Encountered the symbol "CREATE" when expecting one of the following: ...

3 个答案:

答案 0 :(得分:1)

这是一个想法。将前斜杠/(单独在另一行上)设置为终止脚本中每个语句的新标准方式,而不是依赖于分号。例如,您的示例脚本可能变为:

CREATE SEQUENCE SQ_ARAN_SQ_ARQUIVO_ANEXO
/

CREATE OR REPLACE FUNCTION UFC_SPSW_DISP_COMPOSICAO(p_id_composicao IN NUMBER) RETURN NUMBER
IS
   retorno NUMBER:= 0;
   numeroItens NUMBER;
   temDefinicao BOOLEAN := false;

   CURSOR item_cur is
    select idc.itdc_sq_item_definicao_composi, idc.insu_sq_insumo, idc.comp_sq_composicao, idc.itdc_nr_coeficiente, idc.COMP_DS_COMPOSICAO, idc.comp_sq_composicao_pai
    from item_definicao_composicao idc;
  BEGIN  
    FOR item_rec IN item_cur LOOP
      temDefinicao := true;
      IF (item_rec.itdc_nr_coeficiente is null) THEN
        RETURN null;
      ELSE
        IF (item_rec.insu_sq_insumo is null) THEN
          numeroItens := UFC_SPSW_DISP_COMPOSICAO(nvl(item_rec.comp_sq_composicao_pai, item_rec.comp_sq_composicao));
        else
          retorno := retorno + 1;
        END IF;
      END IF;
    END LOOP;
    IF (temDefinicao = false) THEN
       RETURN 0;
    END IF;
    RETURN retorno;
  END;
/

CREATE SEQUENCE SQ_CALC_SQ_CALCULO
/

通过使用/,如果您希望使用SQL * Plus运行它,您的脚本将保持完全有效。但它现在的优点是,在C#中解析语句变得微不足道,这样你就可以单独执行每个语句而不会出现半冒号问题。

我过去曾使用过这种技术而且运作良好。

(如果您不熟悉在Oracle SQL脚本中使用斜杠,请阅读相关内容:When do I need to use a semicolon vs a slash in Oracle SQL?。)

答案 1 :(得分:1)

我有同样的问题并解决了。 同时使用' BEGIN END'并且'执行立即'。

这是我的测试(成功案例)

begin
    EXECUTE IMMEDIATE 'create or replace procedure SP_JHKIM2 IS
        begin
            dbms_output.put_line(''ABC'');
        end;';
end;

答案 2 :(得分:0)

我只使用正则表达式前瞻断言,在LibD之后进行了分割,然后是一些保留字(或文件的末尾)。

例如:

;