web-dev-qa-db-fra.com

Exécutez le bloc de script PL / SQL en C #

J'essaie d'exécuter un bloc PL/SQL en utilisant l'oracleclientProvider dans .NET. La langue que j'utilise est C #, la base de données est oracle10g

Ce que je fais réellement, c'est ce qui suit:

  //ConnectionSting is the connection String
  OracleConnection connection = new OracleConnection(connectionString);
  OracleCommand cmd = new OracleCommand();
  cmd.Connection = connection;

  // Open the connection
  connection.Open();

  //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;

  connection.Open();
  cmd.ExecuteNonQuery(); 
  //close the connection
  connection.close();

Le bloc PL/SQL s'exécute correctement lorsque je l'exécute via Oracle Client, mais ici, il jette une erreur ORA-00922: option manquante ou non valide.

Je veux demander: 1. Les scripts sont-ils exécutés d'une manière différente de la requête normale? 2. Qu'est-ce que je fais mal?

Suggestions/réponses

Merci.

3
Egalitarian

Comme vous ne montrez pas votre script à nous, permet de travailler dans l'autre sens. Créez une table dans votre base de données

Create table Test_call_count (
count number(10)
);
insert into Test_call_count values (0);

et placez ce qui suit dans votre fichier de script

update  Test_call_count set count = count + 1;

Après avoir exécuté votre code, vous pouvez vérifier si cela a fonctionné en sélectionnant dans la base de données.

La prochaine étape consistera à utiliser une certaine fin de début; Bloquer ne renvoyant aucun ensemble de résultats.

Généralement, ADO ne peut pas traiter des scripts entiers. Utilisation de SQL-Server, il peut traiter des lots, qui sont des parties d'un script séparé par des déclarations Go. Pour autant que je sache pour Oracle, il ne peut que traiter une seule déclaration SQL ou un bloc de fin de départ.

EDIT: Voici un litte PowerShell que vous pouvez utiliser pour essayer ce qui est possible:

if ($ora_loaded -eq $null)
{
    $ora_loaded = [System.Reflection.Assembly]::LoadWithPartialName("Oracle.DataAccess") 
}



$ConnectionString = "Data Source=YOUR_TNS;User ID=YOUR_ID;Password=YOUR_Password" 

function Execute-Query
{
    param (
        $sql
    )

        $conn = new-object Oracle.DataAccess.Client.OracleConnection 
        $conn.ConnectionString = $ConnectionString 
        $cmd = new-object Oracle.DataAccess.Client.OracleCommand($sql,$conn)
    #   $cmd.CommandTimeout=$timeout
        $ds = New-Object system.Data.DataSet
        $da = New-Object Oracle.DataAccess.Client.OracleDataAdapter($cmd)
        $nuLL = $da.fill($ds)
        $ds.tables[0]
        Write-Host ''
}

function Execute-NonQuery
{
    param (
        $sql
    )

        $conn = new-object Oracle.DataAccess.Client.OracleConnection 
        $conn.ConnectionString = $ConnectionString 
        $cmd = new-object Oracle.DataAccess.Client.OracleCommand($sql,$conn)
        $conn.open()
    #   $cmd.CommandTimeout=$timeout
        $cmd.ExecuteNonQuery()
        $conn.close()
}

Execute-Query "select * from Test_call_count;"
Execute-NonQuery "update  Test_call_count set count = count + 1"
Execute-NonQuery "begin update  Test_call_count set count = count + 1; end;"

Par exemple, vous voyez, que ce qui suit échoue (j'ai ajouté un point-virgule):

Execute-NonQuery "update  Test_call_count set count = count + 1;"

Et cela échoue aussi:

Execute-NonQuery "begin update  Test_call_count set count = count + 1; end;
/"

Dans une première approximation, vous pouvez penser à la "/" aussi semblable au délimiteur de lot SQL-Server Go.

1
bernd_k

De ma compréhension limitée, les blocs doivent être intégrés dans le C # ou mettre dans un package et appelé. Je l'ai vu comme ça:

@"
BEGIN
   SchemaName.PackageName.ProcedureName(p_LoginID => :loginID, 
      p_Password => :password, p_IPAddr => :ipAddr)";
END;”.Replace(Environment.NewLine, “\n”);
3
Leigh Riffel