2011-03-14 2 views
9

여러 가지 데이터를 데이터베이스에 저장하는 응용 프로그램이 있습니다. 데이터베이스가 ORACLE 또는 SQL Server 일 수 있습니다. SQL은 실행 중에 수집 된 구성 및 값을 기반으로 동적으로 생성됩니다.DbCommand 및 매개 변수화 된 SQL, ORACLE vs SQL Server

DbProviderFactory를 사용하면 내 데이터베이스 메소드가 ORACLE 또는 SQL Server와 함께 작업 할 수 있습니다. 매개 변수/바인드 변수. 오라클의 경우 ":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

는 "값"루프에서 사용되는 형식 문자열을 얻을 수있는 추상적 인 속성을 확인합니다.

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 –

관련 문제