DbCommand 和参数化 SQL、ORACLE 与 SQL Server

DbCommand and parameterized SQL, ORACLE vs SQL Server(DbCommand 和参数化 SQL、ORACLE 与 SQL Server)
本文介绍了DbCommand 和参数化 SQL、ORACLE 与 SQL Server的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,它可以将各种数据存储到数据库中.数据库可能是 ORACLE 或 SQL Server.SQL 是根据执行期间获取的配置和值动态创建的.

I have an application that will, among other things, store various data into a database. The database might be ORACLE or SQL Server. The SQL is created dynamically based on configuration and values picked up during execution.

通过使用 DbProviderFactory,我的 db 方法能够与 ORACLE 或 SQL Server 一起使用,而无需为任何数据库编写自定义代码,除了一件事;参数/绑定变量.对于 ORACLE,我需要使用 ":ParameterName",而对于 SQL Server,我需要使用 "@ParameterName".有没有办法让这个通用?

By using DbProviderFactory my db methods are able to work with either ORACLE or SQL Server without writing custom code for any of the databases, except from one thing; parameters/bind variables. For ORACLE I need to use ":ParameterName" whereas for SQL Server I need to use "@ParameterName". Is there any way to make this generic?

示例代码:

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();
}

推荐答案

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

I accepted an answer for this question long ago, but for some reason that answer is no longer here... So I guess I need to answer my own question.

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

What I did was to create a parambuilder class:

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 类型的成员变量:

I create a member variable of the ParamBuilder type:

private readonly ParamBuilder m_ParamBuilder;

然后在我使用参数的方法中,我使用如下:

Then in the method where I use parameters, I use it as follows:

...
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);
...

这篇关于DbCommand 和参数化 SQL、ORACLE 与 SQL Server的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Batch multiple select statements when calling Oracle from ADO.NET(从 ADO.NET 调用 Oracle 时批处理多个选择语句)
How to get the generated id from an inserted row using ExecuteScalar?(如何使用 ExecuteScalar 从插入的行中获取生成的 id?)
Binding query parameters by name with ODP.NET(使用 ODP.NET 按名称绑定查询参数)
Why the semicolon couldn#39;t place in the CommandText of a OracleCommand when C#(为什么在 C# 时分号不能放在 OracleCommand 的 CommandText 中)
Oracle Stored Procedure and custom data type(Oracle 存储过程和自定义数据类型)
How does fetching data from SQL Server to SqlDataReader work?(从 SQL Server 获取数据到 SqlDataReader 的工作原理是什么?)