2011-03-14 12 views
9

मेरे पास एक ऐसा एप्लीकेशन है जो अन्य चीजों के साथ डेटाबेस में विभिन्न डेटा स्टोर करेगा। डेटाबेस ओरेकल या SQL सर्वर हो सकता है। एसक्यूएल निष्पादन के दौरान उठाए गए विन्यास और मूल्यों के आधार पर गतिशील रूप से बनाया गया है।डीबीकॉमैंड और पैरामीटर एसक्यूएल, ओरेकल बनाम एसक्यूएल सर्वर

डीबीप्रोवाइडर फैक्टरी का उपयोग करके मेरी डीबी विधियां किसी भी डेटाबेस को किसी भी डेटाबेस के लिए कस्टम कोड लिखने के बिना या तो ओरेकल या एसक्यूएल सर्वर के साथ काम करने में सक्षम हैं; पैरामीटर/बाध्य चर। ORACLE के लिए मुझे ":ParameterName" का उपयोग करने की आवश्यकता है जबकि SQL सर्वर के लिए मुझे "@ParameterName" का उपयोग करने की आवश्यकता है। क्या यह सामान्य बनाने का कोई तरीका है?

नमूना कोड:

public class DbOperations 
{ 
    private DbProviderFactory m_factory; 
    private DbConnection m_CN; 

    ... 

    private void InsertToDb(ValueType[] values, ColumnType[] columns) 
    {  
     DbCommand Cmd = m_factory.CreateCommand(); 
     Cmd.Connection = m_CN; 

     StringBuilder sql = new StringBuilder(); 
     sql.Append("INSERT INTO "); 
     sql.Append(DestinationTable); 
     sql.Append(" ("); 

     for (int i = 0; i < columns.Length; i++) 
     { 
      sql.Append(columns[i].ColumnName); 
      if (i < columns.Length - 1) 
      sql.Append(", "); 
     } 
     sql.Append(") VALUES ("); 

     for (int i = 0; i < values.Length; i++) 
     {   
      //sql.Append(String.Format(":{0}", columns[i].ColumnName)); //ORACLE 
      sql.Append(String.Format("@{0}", columns[i].ColumnName)); // SQL Server 
     }  

     DbParameter param = m_factory.CreateParameter(); 
     param.Direction = ParameterDirection.Input; 
     param.ParameterName = columns[i].ColumnName; 
     param.Value = values[i]; 
     Cmd.Parameters.Add(param); 

     if (i < columns.Length - 1)   
      sql.Append(", "); 
     } 
     sql.Append(")"); 
     Cmd.CommandText = sql.ToString(); 
     Cmd.ExecuteNonQuery(); 
} 

उत्तर

5

मैंने बहुत पहले इस प्रश्न का उत्तर स्वीकार कर लिया था, लेकिन किसी कारण से उत्तर अब नहीं है ... तो मुझे लगता है कि मुझे अपने प्रश्न का उत्तर देने की आवश्यकता है।

class ParamBuilder 
{ 
    private DbProviderFactory m_factory; 
    private DbCommandBuilder m_builder; 
    private string m_parameterMarkerFormat; 
    public ParamBuilder(DbProviderFactory factory) : this(factory, null) 
    { 
    } 

    public ParamBuilder(DbProviderFactory factory, DbConnection source) 
    { 
     m_factory = factory; 
     m_builder = m_factory.CreateCommandBuilder(); 
     if (source != null) 
     { 
      using (DataTable tbl = 
       source.GetSchema(DbMetaDataCollectionNames.DataSourceInformation)) 
      { 
       m_parameterMarkerFormat = 
        tbl.Rows[0][DbMetaDataColumnNames.ParameterMarkerFormat] as string; 
      } 
     } 
     if (String.IsNullOrEmpty(m_parameterMarkerFormat)) 
      m_parameterMarkerFormat = "{0}"; 
    } 

    public DbParameter CreateParameter(string parameterName, 
     out string parameterMarker) 
    { 
     DbParameter param = m_factory.CreateParameter(); 
     param.ParameterName = 
      (string)typeof(DbCommandBuilder).InvokeMember("GetParameterName", 
       System.Reflection.BindingFlags.Instance | 
       System.Reflection.BindingFlags.InvokeMethod | 
       System.Reflection.BindingFlags.NonPublic, null, m_builder, 
       new object[] { parameterName }); 

     parameterMarker = 
      String.Format(System.Globalization.CultureInfo.InvariantCulture, 
      m_parameterMarkerFormat, param.ParameterName); 

     return param; 
    } 

} 

मैं ParamBuilder प्रकार के एक सदस्य चर बनाने:

मैं क्या एक parambuilder वर्ग का निर्माण करना था तरीका है जहाँ मैं पैरामीटर का उपयोग में फिर

private readonly ParamBuilder m_ParamBuilder; 

, मैं इसका इस्तेमाल निम्नानुसार:

... 
string paramMarker; 
DbParameter param = m_ParamBuilder.CreateParameter(destination[i].ColumnName, 
    out paramMarker); 
sql.Append(paramMarker); 

param.Direction = ParameterDirection.Input; 
param.Value = source[i]; 
Cmd.Parameters.Add(param); 
... 
2

प्रारूप "मूल्यों" पाश में प्रयोग किया जाता स्ट्रिंग प्राप्त करने के लिए एक अमूर्त संपत्ति करें।

class DBOperations 
public abstract string ParameterStringFormat; 
... 
for (int i = 0; i < values.Length; i++) 
     {   
      sql.Append(String.Format(ParamterStringFormat, columns[i].ColumnName)); // SQL Server 
     } 


class SqlDbOperations : DBOperations 
public override string ParameterStringFormat { get { return "@{0}"; }} 


class OracleDBOperations : DBOperations 
public override string ParameterStringFormat { get { return ":{0}"; }} 
0

यदि आप त्वरित और गंदे चाहते हैं तो बस एक और विकल्प में फेंकना। regex के साथ

string sql = select * from foo there foo.id = @id; 
if (isOracle) { 
sql = replaceAll(sql,"@",":"); 
} 
+1

समाधान: http://stackoverflow.com/questions/35063018/parameterized-sql-oracle-vs-sql-server-with-regular-expresion –

संबंधित मुद्दे