【问题标题】:Problems while executing PL/SQL script block in C#在 C# 中执行 PL/SQL 脚本块时出现问题
【发布时间】:2011-06-28 08:52:13
【问题描述】:

我正在尝试使用 .Net 中的 OracleClientProvider 来执行 PL/Sql 块。我使用的语言是c#,数据库是oracle10g

我实际上在做的是:

//ConnectionSting is the connection String
     OracleConnection connection = new OracleConnection(connectionString);
     OracleCommand cmd = new OracleCommand();
     cmd.Connection = connection;
     //queryFile contains the PL/SQL Script I am trying to execute;
     String queryFile = ConfigurationManager.AppSettings["MasterDbScript"];
     String dataInFile = new StreamReader(queryFile).ReadToEnd();
     cmd.CommandText = dataInFile;
     // Open the connection
     connection.Open();
     cmd.ExecuteNonQuery(); 
     //close the connection
 connection.close();

当我通过 ORACLE 客户端运行 PL/SQL 块时,它可以正确执行,但在这里它会抛出错误 ORA-00922: missing or invalid option

我想问: 1. 脚本的执行方式与普通查询不同吗? 2. 我做错了什么?

建议/答案

脚本:

    Set serveroutput on
  Declare
    tableSize    varchar2(200);
         insertStatement varchar2(200) := 'Insert Into TableAndSize  values (:1,:2,:3,:4) ';
         rowupdateStatement varchar2(200) := 'select count(*) from   :0';
      numOfRows number  := 0;
      dataType       nvarchar2(200);

  queryConstruct varchar2(10000);
      tableNameInUserTabColumns nvarchar2(4000);
      num NUMBER :=0;
      zero number := 0 ;
      nums nvarchar2(4000);
      fields nvarchar2(1000);
      fieldSet nvarchar2(1000);
      columnName nvarchar2(1000);
      dummy nvarchar2(1000);
      Cursor Table_Names is  select Distinct TABLE_NAME from user_tab_columns where TABLE_NAME not like 'BIN%' and table_name != 'TABLEANDSIZE' order by table_name;

begin
execute immediate 'truncate table tableandsize';
open Table_Names;
  fetch Table_Names into tableNameInUserTabColumns;

while Table_Names%found
          loop
              DBMS_OUTPUT.PUT_LINE(tableNameInUserTabColumns);
                  queryConstruct := 'select nvl( sum (';
                  --DBMS_OUTPUT.PUT('select sum (');
                          Declare
                              detailsOftableInScope user_tab_columns%rowtype;
                              cursor tableDetails is select * from user_tab_columns where table_name = tableNameInUserTabColumns;

                          Begin
                              open tableDetails;
                              fetch tableDetails into detailsOftableInScope;
                                  while tableDetails%found
                                      loop
                                          dataType := detailsOftableInScope.DATA_TYPE;
                                              if dataType = 'CLOB' then
                                                    fields := 'nvl(DBMS_LOB.GETLENGTH(' || detailsOftableInScope.COLUMN_NAME ||'),0)';
                                              elsif dataType = 'BLOB' then
                                                      fields := 'nvl(DBMS_LOB.GETLENGTH('|| detailsOftableInScope.COLUMN_NAME ||'),0)';
                      elsif dataType = 'LONG' then
                                                          fields := 'nvl(VSIZE(''''),0)';
                                                  else
                                                      fields := 'nvl(vsize(' || detailsOftableInScope.COLUMN_NAME || '),0)';
                                              end if;
                                                  --DBMS_OUTPUT.PUT('*****'||fields);
                                          fetch tableDetails into detailsOftableInScope;
                                                  if tableDetails%found then
                                                  --DBMS_OUTPUT.PUT(''||fields||'+');
                                                  queryConstruct := queryConstruct || fields||'+';
                                                  else
                                                  --DBMS_OUTPUT.PUT(''|| fields);
                                                  queryConstruct := queryConstruct || fields;
                                                  DBMS_OUTPUT.ENABLE(100000);
                                                  end if;
                                      end loop;
                                  close tableDetails;
                          end;
                                  --DBMS_OUTPUT.PUT_LINE(') as sizeOfTable from  ' ||tableNameInUserTabColumns);
                                  queryConstruct := queryConstruct || '),0) as sizeOfTable from  ' ||tableNameInUserTabColumns;
                                  DBMS_OUTPUT.PUT_LINE('Query Being Fired To calculate the size of Data in Table  '||tableNameInUserTabColumns || ' --->  '||queryConstruct);
               execute immediate queryConstruct  into num;
                                  execute immediate insertStatement using tableNameInUserTabColumns,num,zero,zero;
                                  --DBMS_OUTPUT.PUT_LINE(num);
                  fetch Table_Names into tableNameInUserTabColumns;
          end loop;
  close Table_Names;
----finding number of rows and size of index
declare
      sumTotal number := 0;
      tableNameInUserTabColumns nvarchar2(4000);
      updateStatement varchar2(400);
  cursor Table_Names is select distinct(table_name) from user_tab_columns  where TABLE_NAME not like 'BIN%' and table_name != 'TABLEANDSIZE' order by table_name;
begin
open Table_Names;
dbms_output.put_line('*********************finding index size and number of rows******************************');
  fetch Table_Names into tableNameInUserTabColumns;
while Table_Names%found
          loop
          dbms_output.put_line('TABLE ---  '||tableNameInUserTabColumns);
              declare
                  Index_Name nvarchar2(4000);
                  size1 number := 0 ;
                  size2 number := 0 ;
                  tableIndexSize number := 0;
                  sizeOfIndexInTable number :=0 ;
                  sql_statement varchar2(1000) := 'select nvl(USED_SPACE,0) from index_stats';
                  stat1 varchar2(1000) := 'analyze index ';
                  stat2 varchar2(1000) := '  validate structure';
                  stat3 varchar2(2000) := '';
                  sum1 number := 0;
                  sum2 number := 0 ;
                  cursor indexOnTable is select Index_name from user_indexes where table_name = tableNameInUserTabColumns and index_type = 'NORMAL';
                  begin
                  open indexOnTable;
                  fetch indexOnTable into Index_Name;
                  while indexOnTable%found
                  loop
                      dbms_output.put_line('****  '||Index_Name);
                      DBMS_OUTPUT.ENABLE(100000);
                                          stat3 := stat1 || Index_Name || stat2;
                                          execute immediate stat3;
                                          execute immediate  sql_statement into size1;
                                          dbms_output.put_line('Query being fired to find size of index = '|| Index_Name || 'in table = ' || tableNameInUserTabColumns || '===>>' || stat3 ||' And ' ||sql_statement);
                                          tableIndexSize := tableIndexSize + size1;
                                          --dbms_output.put_line(size1);
                                          sumtotal:= sumtotal + size1  ;
                                          --dbms_output.put_line(sumtotal);
                      fetch indexOnTable into Index_Name;
                  end loop;
                          rowupdateStatement := 'select count(*) from  '|| tableNameInUserTabColumns;
            dbms_output.put_line('Query to find number of rows in '|| tableNameInUserTabColumns || ' --> '||rowupdateStatement);
                          execute immediate rowupdateStatement into numOfRows;
                          --dbms_output.put_line('----'||numofrows ||'-----');
                      updateStatement := 'update tableAndsize set indexsize = :0, RowNumber = :1 where tablename = :2';
                          --    dbms_output.put_line('----'||tableIndexSize ||'*****'||tableNameInUserTabColumns);
                     execute immediate updateStatement using tableIndexSize,numOfRows,tableNameInUserTabColumns ;
                      --dbms_output.put_line(tableIndexSize);
                      --dbms_output.put_line(updateStatement);

                  close indexOnTable;
              end;
          fetch Table_Names into tableNameInUserTabColumns;
          end loop;
close Table_Names;
end;
end;

谢谢。

【问题讨论】:

    标签: c# .net oracle10g


    【解决方案1】:

    问题在于您的 SQL 脚本的最顶部:“Set serveroutput on”

    必须删除所有 PL/SQL 特定指令才能通过 C# 运行我的脚本。

    【讨论】:

      【解决方案2】:

      只是猜测,但我注意到连接被打开了两次,请尝试删除其中一行。如果这不起作用,您可以发布您要运行的查询示例吗?

      文件是否可能使用 Unicode(UTF-16 或 UTF-8)编码,并且流试图将其读取为 ASCII?

      您是否查看过字符串的内容以确保没有“有趣”字符?

      【讨论】:

      • 哦,这不是问题。仅在调用 cmd.executeNonQuey 时才会出现此问题。此外,该字符串不包含有趣的字符。我将发布查询
      • 脚本确实包含插入和更新但它试图修改/插入的表的字段可以包含 NULL 值
      • 脚本找出表空间中每个表的表数据和索引大小
      • 根据有关错误 ORA-00922 的一些文档,它指出脚本正在尝试对数据类型不允许的列应用约束。例如,指定数据类型为 int 的列的长度。您可以尝试在执行 ExecuteNonQuery 之前放置一个断点,获取 dataInFile 中的内容,然后在 ORACLE 客户端中执行它,如果它中断,那么在从文件中提取时,sql 中会产生某种语法错误。跨度>
      • hmm,只是另一个猜测,但你可以尝试设置 cmd.CommandType = CommandType.Text,不确定 OracleProvider 是否需要。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 2020-10-28
      • 1970-01-01
      • 2019-07-16
      相关资源
      最近更新 更多