C#およびOracle-マージナルノート-2

私はほとんどCLOBを忘れていました。




私は歩きません、興味がある人は前のトピックに慣れることができます







ここで、Oracleデータベースでコードを動作させたいと思います(多くのテキストが注がれ、UFOがフォレストによる保存のプロセスを送信したため、前のトピックには挿入しませんでした)。



一般に、CLOB(LOB \ BLOB)は非常に興味深いものです。 これを操作することは、他のオブジェクトを操作することとは異なります。 MSDNの詳細な説明もご覧ください

私はそれを次のようなことをするためだけに言うことができます:



OracleParameter someClob = new OracleParameter()

{

ParameterName = "some_clob" ,

Direction = ParameterDirection.Input,

OracleType = OracleType.Clob,

Value = clobData

};








動作しません、アプローチは薄くする必要があります。



甘いもの


プログラマーとデザイナー、そしておそらくすべての人には共通点が1つあります。それを「MakeItPizdatoボタン」と呼びます。 つまり どんな場合でも、最大の効率性\生産性\代替品を最低のコストで入手することができます。

そのため、私は自分のコードを書きました(批評にのみ喜んでいます!しかし、合理的な批評には;))、私はそれを共有することにしました



データベースの操作は、いくつかの部分に分かれています。

ファクトリー-データベースのすべての作業を担当します



using System;

using System.Collections. Generic ;

using System.Data;

using System.Data.OracleClient;

using System.Linq;

using Core.Extensions;



namespace TestApp.Core

{

class OracleFactory : IDisposable

{

#region Variables

private bool _disposed = false ;



private String _connectionString = "Data Source=***;Password=***;User ID=***" ;

private OracleConnection _connection;

private String _lastCommandName;

#endregion



#region Constructor



public OracleFactory()

{

InitializeConnection();

}



public OracleFactory( String connectionString)

{

_connectionString = connectionString;

InitializeConnection();

}



private void InitializeConnection()

{

Commands = new Dictionary< String , OracleCommand>();

RollbackCommandNames = new List < string >();



try

{

_connection = new OracleConnection(_connectionString);

_connection.Open();

}

catch (OracleException oraEx)

{

Console .WriteLine( "Connection failed with message: " + oraEx.ToString());

}

}



#endregion



#region IDisposable

~OracleFactory()

{

Dispose( false );

}



public void Dispose()

{

Dispose( true );

GC.SuppressFinalize( this );

}



protected virtual void Dispose( bool disposeManagedResources)

{

if (!_disposed)

{

foreach ( String commandName in Commands.Keys)

{

if (RollbackCommandNames.Contains(commandName))

Commands[commandName].Transaction.Rollback();

else

Commands[commandName].Transaction.Commit();

}



if (disposeManagedResources)

{

foreach ( String commandName in Commands.Keys)

{

Commands[commandName].Dispose();

}

//Dispose connection information

_connection.Close();

_connection.Dispose();

}



_disposed = true ;

}

}

#endregion



public OracleConnection Connection

{

get

{

return (_connection);

}

}



public Dictionary< String , OracleCommand> Commands

{

get ;

private set ;

}



public List < String > RollbackCommandNames

{

get ;

private set ;

}



/// <summary>

/// Last used command name

/// </summary>

/// <exception cref="System.ArgumentException"/>

public String LastCommandName

{

get

{

if (_lastCommandName == String .Empty)

throw new ArgumentException( "LastCommandName is not specified" );



return (_lastCommandName);

}

set

{

_lastCommandName = value ;

}

}



/// <summary>

/// Last used command

/// </summary>

public OracleCommand LastCommand

{

get

{

return (Commands[LastCommandName]);

}

}



public Object this [ String commandName, String parameterName]

{

get

{

if (!Commands.Keys.Contains(commandName))

throw new OracleFactoryException();



return (Commands[commandName].Parameters[parameterName].Value);

}

set

{

Commands[commandName].Parameters[parameterName].Value = value ;

}

}



public Object this [ String parameterName]

{

get

{

return ( this [LastCommandName, parameterName]);

}

set

{

this [LastCommandName, parameterName] = value ;

}

}



/// <summary>

/// Allow get oracle parameter value

/// </summary>

/// <typeparam name="T"></typeparam>

/// <param name="parameterName">Oracle parameter name</param>

/// <returns>Oracle parameter value</returns>

/// <exception cref="System.InvalidCastException"/>

/// <exception cref="System.ArgumentNullException" />

public T GetParameterValue<T>( String parameterName)

{

return ((T) Convert .ChangeType( this [parameterName], typeof (T)));

}



/// <summary>

/// Creates a new Oracle`s command (default for stored procedures)

/// </summary>

/// <exception cref="Core.DL.OracleManagerException">

/// </exception>

/// <param name="commandName">Oracle`s command name</param>

public void CreateCommand( String commandName)

{

CreateCommand(commandName, CommandType.StoredProcedure);

}



/// <summary>

/// Creates a custom Oracle`s command

/// </summary>

/// <exception cref="Core.DL.OracleManagerException">

/// </exception>

/// <param name="commandName">Oracle command name</param>

/// <param name="commandType">Oracle command type</param>

public void CreateCommand( String commandName, CommandType commandType)

{

if (Commands.Keys.Contains(commandName))

throw new OracleFactoryException();



LastCommandName = commandName;



Commands[commandName] = new OracleCommand(commandName, _connection);

Commands[commandName].CommandType = commandType;

Commands[commandName].Transaction = Connection.BeginTransaction();

}



public void ClearParameters()

{

LastCommand.Parameters.Clear();

}



public void AddParameter( String parameterName, OracleType parameterType, Object parameterValue)

{

AddParameter(LastCommandName, parameterName, parameterType, parameterValue, ParameterDirection.Input);

}



public void AddParameter( String parameterName, OracleType parameterType, Object parameterValue, ParameterDirection parameterDirection)

{

AddParameter(LastCommandName, parameterName, parameterType, parameterValue, parameterDirection);

}



public void AddParameter( String commandName, String parameterName, OracleType parameterType,

Object parameterValue, ParameterDirection parameterDirection)

{

if (!Commands.Keys.Contains(commandName))

throw new OracleFactoryException();



if (parameterType == OracleType.Clob)

parameterValue = OracleFactory.PrepareCLOB(Commands[commandName], parameterValue.ToString());



Commands[commandName].Parameters.Add( new OracleParameter(parameterName, parameterType)

{

Direction = parameterDirection,

Value = parameterValue ?? DBNull.Value

});

}



public void ExecuteNonQuery()

{

ExecuteNonQuery(LastCommandName);

}



public void ExecuteNonQuery( String commandName)

{

if (! this .Commands.ContainsKey(commandName))

throw new OracleFactoryException();



Commands[commandName].ExecuteNonQuery();

}



public OracleDataReader ExecuteReader()

{

return (ExecuteReader(LastCommandName));

}



public OracleDataReader ExecuteReader( String commandName)

{

OracleDataReader dataReader = Commands[commandName].ExecuteReader();



return (dataReader);

}



public void Rollback( String commandName)

{

if (!RollbackCommandNames.Contains(commandName))

{

RollbackCommandNames.Add(commandName);

}

}



public void Rollback()

{

Rollback(LastCommandName);

}



#region Static members



public static OracleLob PrepareCLOB(OracleCommand command, String data)

{

OracleLob clob = CreateLob(command, OracleType.Clob);

byte [] byteData = System.Text. Encoding .Unicode.GetBytes(data);



clob.BeginBatch(OracleLobOpenMode.ReadWrite);

clob.Write(byteData, 0, byteData.Length);

clob.EndBatch();



return (clob);

}



public static OracleLob CreateLob(OracleCommand command, OracleType lobType)

{

if (command.Transaction == null )

throw new OracleFactoryException( "Parameter command should contains transaction value" );



if (lobType != OracleType.Clob && lobType != OracleType.Blob)

throw new OracleFactoryException( "Thhis method is used only for creation LOB objects" );



////Save previous information about a command

String previousCommand = command.CommandText;

CommandType previousCommandType = command.CommandType;

OracleParameterCollection previousParameters = new OracleParameterCollection();

command.Parameters.MakeClone(previousParameters);



//Prepare for creating LOB object

command.Parameters.Clear();



command.CommandType = CommandType.Text;

command.CommandText = String .Format( "declare xx {0}; begin dbms_lob.createtemporary(xx, false, 0); :tempLob := xx; end;" ,

lobType == OracleType.Clob ? "clob" : "blob" );

command.Parameters.Add( new OracleParameter( "tempLob" , lobType) { Direction = ParameterDirection.Output });

command.ExecuteNonQuery();



OracleLob retLob = command.Parameters[ "tempLob" ].Value as OracleLob;



command.Parameters.Clear();



command.CommandText = previousCommand;

command.CommandType = previousCommandType;

previousParameters.MakeClone(command.Parameters);



return (retLob);

}



#endregion

}

}









拡張機能の使用にはまっています。 そして、LOBタイプ(保存してから復元)で使用するパラメーターのコレクションを準備する必要があるという事実の一部として、この拡張機能を思い付きました。



using System.Data.OracleClient;



namespace Core.Extensions

{

public static class OracleParameterCollectionExtensions

{

public static void MakeClone( this OracleParameterCollection sourceCollection, OracleParameterCollection outCollection)

{

foreach (OracleParameter parameter in sourceCollection)

{

OracleParameter newParam = new OracleParameter()

{

Direction = parameter.Direction,

IsNullable = parameter.IsNullable,

OracleType = parameter.OracleType,

ParameterName = parameter.ParameterName,

Value = parameter.Value

};



outCollection.Add(newParam);

}

}

}

}




* This source code was highlighted with Source Code Highlighter .








今日このコードの使用を開始すると、+例外!:が無料で得られます。



using System;



namespace TestApp.Core

{

public class OracleFactoryException : Exception

{

public OracleFactoryException()

{

}



public OracleFactoryException( String exMessage)

: base (exMessage)

{



}

}



}









私にとっては、体の動きが少なくなりましたが、追加は次のようになります。



public void AddConscript( string firstName, string lastName, int ages, float growth, string biograpby)

{

using (OracleFactory factory = new OracleFactory())

{

factory.CreateCommand( "ADD_CONscript" );



factory.AddParameter( "FirstNameIn" , OracleType.VarChar, firstName);

factory.AddParameter( "LastNameIn" , OracleType.VarChar, lastName);

factory.AddParameter( "AgesIn" , OracleType.Number, ages);

factory.AddParameter( "GrowthIn" , OracleType.Float, growth);

factory.AddParameter( "BiographyIn" , OracleType.Clob, biograpby);

}

}








コードが簡素化され、他のタイプに対して同じCLOBを透過的に使用できます。

次のように特定のパラメーターの値を取得する必要がある場合:



factory.GetParameterValue< String >( "BiographyIn" );







コードを深く掘り下げると、さらに多くの興味深いことがわかります;)。



なぜCLOBなのでしょうか? 私は答えます-私はまだ他のLOBを必要としませんでしたが、私は自分のためにコードを研ぎました;)。



All Articles