私はほとんど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を必要としませんでしたが、私は自分のためにコードを研ぎました;)。