2011-03-14 66 views
9

我有一个应用程序,将,除其他事项外,各种数据存储到数据库中。 数据库可能是ORACLE或SQL Server。 SQL是基于配置和执行期间获取的值动态创建的。的DbCommand和参数化的SQL,ORACLE VS SQL服务器

通过使用DbProviderFactory我的分贝方法能够与Oracle或SQL Server一起工作,而无需编写自定义代码对任何数据库,除了从一两件事;参数/绑定变量。对于ORACLE我需要使用":ParameterName"而对于SQL Server的我需要使用"@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

我早就接受了这个问题的答案,但由于某种原因,答案不再在这里......所以我想我需要回答我自己的问题。

我所做的是创建一个parambuilder类:

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类型的成员变量:在我使用参数的方法

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

只是抛出另一个选项,如果你想快速和肮脏。

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 – 2016-01-28 14:37:28