0

I am working on a big solution in C#. This solution uses different oracle databases and is checked in in TFS. Actually I develop a small library which can deploy the SQL Scripts in the solution to the used databases. The deployment of the application is handled with TFS and in the future my tool should be included in the build process. For the Oracle Connection an execution of the statements I use Oracle.ManagedDataAccess.Client.

If there are only several DDL or DML statements in the SQL Files the first tests were successful. But there are a few special special things I have to handle, like SET DEFINE OFF. This is no real SQL Statement and if I run the Script with ORacle SQL*PLus there is no problem. In the beginning I tried to execute the whole script but this doesn't work because multiple statements were put in one line by my application and the only solution I found was the splitting of the file and single execution.

Example:

Folder and File Structure

   /*************************************************************************************************************************
##NAME   ScriptName.sql
##DESCR  ScriptDescription
*************************************************************************************************************************/

Create table tmp_thm_Test
( tmp_thm_Test_id number(8)
, text varchar2(200));

Create table tmp_thm_Test2
( tmp_thm_Test2_id number(8)
, text varchar2(200));

This is an example content for a script. Also there can be Insert (Set Define off is needed while having the & in strings), Update Statements. Also Begin/End Scripts.

If there are only DDL and DML Statements I can split them but Begin/End parts are not splittable. At the beginning I thought I can deploy a script like in the past with SQL*Plus (@Scriptname.sql). Read the whole script an execute it.

Any ideas?

2
  • It's not entirely clear what you are asking. Can you provide the code that you tried (reduced to a minimal, complete and verifiable example), describe what you expect to happen and what actually happens? SET DEFINE OFF is a setting of SQL*Plus, not of the Oracle DB server. You should never need this in script executed through ODP.Net Commented Aug 14, 2018 at 6:07
  • Hi jeroenh, i've edited my post with additional Informations. Commented Aug 14, 2018 at 8:45

1 Answer 1

1

Since I've worked with Oracle in C# before I kind of understand you even with the lack of concrete samples.

SET DEFINE OFF never worked for me in C#, so I simply use query = query.Replace("'","''");. You could also use command parameters like the one below to avoid exceptions.

        string query = string.Format(
                                    @"UPDATE CardStatus
                                      SET DateExpired = @dateExpired,
                                          ModifiedBy = @modifiedBy,
                                          ModifiedOn = @modifiedOn
                                      WHERE
                                        IDNo = @idNo");

        List<OracleParameter> parameters = new List<OracleParameter>();

        OracleParameter pIdNo = new OracleParameter("idNo", OracleDbType.Varchar2);

        pIdNo.Value = idNo;

        OracleParameter pDateExpired = new OracleParameter("dateExpired", OracleDbType.Date);

        pDateExpired.Value = dateExpired;

        OracleParameter pModifiedBy = new OracleParameter("modifiedBy", OracleDbType.Varchar2);

        pModifiedBy.Value = "SIS";

        OracleParameter pModifiedOn = new OracleParameter("modifiedOn", OracleDbType.Date);

        pModifiedOn.Value = DateTime.Now;

        parameters.Add(pIdNo);
        parameters.Add(pDateExpired);
        parameters.Add(pModifiedBy);
        parameters.Add(pModifiedOn);

        bool result = _DAL.ExecuteNonQuery(query, parameters.ToArray());

_DAL is simply my helper class for data access, it manages the query executions placing it inside a single transaction so that I get to decide whether to commit or rollback the changes of single to multiple queries.

    public bool ExecuteNonQuery(string query, object[] parameters, [CallerMemberName] string callerMemberName = "")
    {
        bool success = false;

        try
        {
            using (OracleCommand command = new OracleCommand())
            {
                command.Connection = _connection;
                command.Transaction = _transaction;
                command.CommandText = query;
                command.CommandType = CommandType.Text;
                command.Parameters.AddRange(parameters);

                command.ExecuteNonQuery();
            }

            this.AuditSQL(query, string.Empty);
            success = true;
        }
        catch (OracleException ex)
        {
            this.AuditSQL(query, ex.Message, callerMemberName);

            if (ex.Number == 54) // SELECT .. FOR UPDATE NOWAIT failed.
            {
                throw new RowLockException();
            }
        }

        return success;
    }

I am not sure if you are interested in looking at my _DAL class but I provided you a snippet to give you an idea of what you can do.

EDIT: Since you've mentioned that the scripts already exists then it is easier, you just have to make sure that there is no ' character within the script to make oracle ask for a variable value and all batch queries must have BEGIN and END;.

Example:

BEGIN

-- INSERT
-- UPDATE
-- INSERT
... etc.

END;

Now, what exactly is your problem? You can read the query from the file and replace all SET DEFINE OFF (as well as other statements you deem unnecessary) with string.Empty and replace all ' with '' if needed. Worst case, you would be using regex to identify and remove unwanted statements.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi John, thanks for your feedback. I've a similar solution. Also with handling of the qoutes and the execution of the statements. Unfortunately, this is not the solution to my problem. I have whole sql-script files to execute. I've added more informations in my post. kind regards Tobi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.