在Oracle ADO.NET中绑定Guid参数

时间:2014-05-05 20:07:11

标签: c# oracle binding ado.net

我有一个C#应用程序(.NET framework 4.0),它使用来自Oracle的Oracle.DataAccess.dll提供程序使用Instant Client(v.11.2.0.1)访问Oracle数据库。

我的表有2列:Id(类型RAW)和名称(类型VARCHAR2)。

我可以运行SELECT并正确绑定Id参数。但是,当我在Update中尝试完全相同类型的绑定时,该行永远不会更新。

这是一个展示我问题的示例程序。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Oracle.DataAccess.Client;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Transactions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string connectString = ConfigurationManager.ConnectionStrings["testOracle"].ConnectionString;
            Guid id = Guid.Parse("590704389D204D979A8BA775F000F300");

            using (OracleConnection connection = new OracleConnection(connectString))
            {
                connection.Open();

                using (OracleCommand command = connection.CreateCommand())
                {
                    command.CommandType = CommandType.Text;
                    command.CommandText = "SELECT Id, Name FROM Enterprise WHERE Id = :Id";

                    command.Parameters.Add(":Id", id.ToString("N").ToUpper());

                    using (OracleDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Trace.WriteLine(string.Format("ID:  {0}, Name:  {1}",
                                                          new Guid((byte[])reader["Id"]),
                                                          reader["Name"]));
                        }
                    }
                }

                using (OracleCommand command = connection.CreateCommand())
                {
                    command.CommandType = CommandType.Text;
                    command.CommandText = "UPDATE Enterprise SET Name = :Name WHERE Id = :Id";

                    command.Parameters.Add(":Id", id.ToString("N").ToUpper());
                    command.Parameters.Add(":Name", "xxxx");

                    Trace.WriteLine(string.Format("Rows affected:  {0}", command.ExecuteNonQuery()));
                }

                using (OracleCommand command = connection.CreateCommand())
                {
                    command.CommandType = CommandType.Text;
                    command.CommandText = "SELECT Id, Name FROM Enterprise WHERE Id = :Id";

                    command.Parameters.Add(":Id", id.ToString("N").ToUpper());

                    using (OracleDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            Trace.WriteLine(string.Format("ID:  {0}, Name:  {1}",
                                                          new Guid((byte[])reader["Id"]),
                                                          reader["Name"]));
                        }
                    }
                }
            }
        }
    }
}

我的程序总是输出:

ID:  38040759-209d-974d-9a8b-a775f000f300, Name:  bbbbb
Rows affected:  0
ID:  38040759-209d-974d-9a8b-a775f000f300, Name:  bbbbb

我也尝试过以下声明,但仍然失败

UPDATE Enterprise SET Name = :Name WHERE rowid = (SELECT rowid FROM Enterprise WHERE Id = :Id)

如何绑定我的Id参数以便我的Update开始工作?

1 个答案:

答案 0 :(得分:0)

我终于明白了。

事实证明,Oracle的默认行为是按照查询中定义的顺序绑定参数。

为了使我的示例程序正常工作,我有两个解决方案。

1 - 切换参数绑定的顺序

更改

command.CommandType = CommandType.Text;
command.CommandText = "UPDATE Enterprise SET Name = :Name WHERE Id = :Id";

command.Parameters.Add(":Name", "toto");
command.Parameters.Add(":Id", id.ToString("N").ToUpper());

command.CommandType = CommandType.Text;
command.CommandText = "UPDATE Enterprise SET Name = :Name WHERE Id = :Id";

command.Parameters.Add(":Id", id.ToString("N").ToUpper());
command.Parameters.Add(":Name", "toto");

2 - 使用BindByName

BindByName属性设置为true

command.CommandType = CommandType.Text;
command.BindByName = true;
command.CommandText = "UPDATE Enterprise SET Name = :Name WHERE Id = :Id";

command.Parameters.Add(":Id", id.ToString("N").ToUpper());
command.Parameters.Add(":Name", "toto");