gpt4 book ai didi

C# ADO.NET IBM DB2 命名参数具有相同的名称抛出没有足够的参数指定异常

转载 作者:可可西里 更新时间:2023-11-01 09:16:10 25 4
gpt4 key购买 nike

我有一个相当不可知的 ADO.NET 应用程序,它连接到许多数据库并且能够提取必要的信息来运行。我遇到了 DB2 及其处理命名参数的问题,尤其是当我在同一个查询中重用命名参数时。我知道有几种方法可以通过简单地添加更多参数来解决这个问题,但理论上它应该像在我连接的其他数据库上一样工作,因为参数名称相同。

我正在做的事情有点复杂,涉及子查询等,但为了演示,采用以下查询:

从 test.table 中选择值,其中 cola=@key1 和 colb=@key1;

命名参数@key1被使用了两次。

我的代码如下:

       try
{
DbProviderFactory dbfFactory = DbProviderFactories.GetFactory("IBM.Data.DB2.iSeries");
using (DbConnection dbConnection = dbfFactory.CreateConnection())
{
dbConnection.ConnectionString = "DataSource=xxx.xxx.xxx.xxx;UserID=xxxxxxxx;password=xxxxxxxxx";

using (DbCommand dbCommand = dbConnection.CreateCommand())
{
IDbDataParameter iddpParameter1 = dbCommand.CreateParameter();
iddpParameter1.ParameterName = "@key1";
iddpParameter1.DbType = DbType.String;
iddpParameter1.Value = "1";

dbCommand.Parameters.Add(iddpParameter1);
dbCommand.CommandType = CommandType.Text;
dbCommand.CommandText = "select value from test.table where cola=@key1 and colb=@key1";
dbConnection.Open();

using (IDataReader idrReader = dbCommand.ExecuteReader())
{
while (idrReader.Read())
{
...
}
}
}

} // end dbConnection
} // end try

catch (Exception ex)
{
Console.Write(ex.Message);
}

当我运行它时,我得到一个异常告诉我:

System.InvalidOperationException: Not enough parameters specified.  The command requires 2 parameter(s), but only 1 parameter(s) exist in the parameter collection.

我明白它告诉我的内容,但我正在寻求帮助,以弄清楚如何让提供者对两个参数使用命名参数,因为它们是相同的。似乎它正在对命名参数进行盲目计数,而没有意识到它们是相同的命名参数。 SQL Server 似乎允许我使用上面的相同代码来执行此操作。我猜这只是提供程序中的差异之一,但希望有人遇到过这个问题并有一个不涉及特定 DB2 代码的 DB2 解决方案。

谢谢,感谢您的帮助。

最佳答案

好吧,我做了更多的挖掘,我想知道它是否可能是您正在使用的连接器。所以我正在做以下事情(这与你正在做的事情非常相似)

在我的应用配置文件中有

<connectionStrings>
<add name="AWOLNATION" providerName="Ibm.Data.DB2" connectionString="Server=sail:50000;Database=Remix;" />
</connectionStrings>

在我的 Databasemanager 类中,我会像这样初始化它

    public static DatabaseManager Instance(string connectionStringName)
{
var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
if (connectionStringSettings == null) throw new MissingMemberException("[app.config]", string.Format("ConnectionStrings[{0}]", connectionStringName));
return new DatabaseManager(connectionStringSettings);
}

private DatabaseManager(ConnectionStringSettings connectionInformation)
{
_connectionInformation = connectionInformation;
_parameters = new Dictionary<string, object>();
}
private void Initialize()
{
_connection = DbProviderFactories.GetFactory(_connectionInformation.ProviderName).CreateConnection();
_connection.ConnectionString = _connectionInformation.ConnectionString;

_command = _connection.CreateCommand();
}

不过我添加的参数有点不同。我有一个 Dictionary<string,object>我在设置查询时也添加了。要使用你的例子,我会有这个

    public IEnumerable<object> GetSomething(string key)
{
var sql = "select value from test.table where cola = @key1 and colb = @key1";
_manager.AddParameter("@key1", key);

return _manager.ExecuteReader<object>(sql, ToSomethignUseful);
}

private object ToSomethignUseful(DatabaseManager arg)
{
return new { Value = arg.GetArgument<object>("value") };
}

然后阅读是 OP 和我有相似代码的地方

    public IEnumerable<T> ExecuteReader<T>(string sql, Func<DatabaseManager, T> conversionBlock)
{
Initialize();
using (_connection)
{
_connection.Open();
_command.CommandText = sql;
_command.CommandType = CommandType.Text;

if (_parameters.Count > 0)
AddParameters(_command, _parameters);

_parameters.Clear();

using (_reader = _command.ExecuteReader())
{
while (_reader.Read())
{
yield return conversionBlock(this);
}
}
}
}
private static void AddParameters(DbCommand command, Dictionary<string, object> parameters)
{
foreach (var param in parameters)
{
command.Parameters.Add(CreateParameter(command, param.Key, param.Value));
}
}

private static DbParameter CreateParameter(DbCommand command, string key, object value)
{
var parameter = command.CreateParameter();
parameter.ParameterName = key;
parameter.Value = value;

return parameter;
}

运行上述代码对我有用,所以我想知道区别是否在于我们使用的提供程序。我在生产中使用命名参数,现在至少使用了一年,可能接近 2 年。

我要说的是,我确实在两次运行相同的代码时遇到了同样的错误,如这段代码所示

    public static void IndendedPrintForEach<T>(this IEnumerable<T> array, string header, Func<T, string> consoleStringConverterMethod)
{
var list = array.ToList();
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine($"<<<{header}>>>");
Console.ForegroundColor = color;

if (!list.Any())
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine(" ************NoItemsFound************");
Console.ForegroundColor = color;
}
else
{
foreach (var item in list)
Console.WriteLine($" {consoleStringConverterMethod(item)}");
}
}

第 3 行 var list = array.ToList()是您为我看到的问题的解决方案。在我有if (!array.Any())之前这将运行查询并使用参数(我在执行查询之前清除了这些参数)然后当我去枚举并打印数组中的每个项目时我得到了错误。对我来说,问题是它正在重新运行我没有更多参数的查询。解决方法是使用 ToList() 枚举查询,然后在列表上进行检查和打印。

关于C# ADO.NET IBM DB2 命名参数具有相同的名称抛出没有足够的参数指定异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24070890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com