【问题标题】:Parameters do not pass to a MySql stored procedure from F#参数不会从 F# 传递给 MySql 存储过程
【发布时间】:2020-06-13 01:37:57
【问题描述】:

我想使用 F# 中的参数调用存储过程,但它会导致异常“MySql.Data.MySqlClient.MySqlException (0x80004005): PROCEDURE test.GetValue 的参数数量不正确;预期为 1,得到 0” .

C# 中的类似代码完美运行。

这是 .NetCoreApp3.1、FSharp.Core/4.7.0 和 MySql.Data/8.0.20。 MySql 服务器是 8.0.20,操作系统是 Ubuntu 18.04.4 LTS。

问题:我在做某事吗?错了还是bug?

注意:如果我从存储过程中删除参数并在其 SELECT 查询中对其进行硬编码,则它在 F# 中可以正常工作。另外,在调试的时候,可以看到调用前的参数完美到位。

导致异常的F#代码:

module test_mysql_fsharp.main

open System
open System.Data
open MySql.Data.MySqlClient

[<EntryPoint>]
let main argv =
    Console.WriteLine("Hello from test_mysql_fsharp !");
    let execStoredProc cs storedProcedureName storedProcedureParameters =
        use mySqlConnection = new MySqlConnection(cs)
        use command = new MySqlCommand(storedProcedureName, mySqlConnection)
        command.CommandType = CommandType.StoredProcedure |> ignore
        storedProcedureParameters |> List.iter(fun par -> command.Parameters.AddWithValue(par) |> ignore)
        mySqlConnection.Open()
        let dataTable = new DataTable()
        dataTable.Load(command.ExecuteReader())
        dataTable
    let cs = "server=127.0.0.1;port=3306;database=test;Uid=***;Pwd=***;"
    execStoredProc cs "GetValue" [("par0","KA")] |> ignore
    0 

C# 中的类似代码完美运行:

using System;
using System.Collections.Generic;
using System.Data;
using MySql.Data.MySqlClient;

namespace test_mysql_csharp
{
    static class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello from test_mysql_csharp !");
            var cs = "server=127.0.0.1;port=3306;database=test;Uid=***;Pwd=***;";
            var sp = "GetValue";

            var ps = new List<MySqlParameter>();
            var p = new MySqlParameter("par0", "KA");
            ps.Add(p);
            var b = ExecStoredProc(cs, sp, ps.ToArray());
        }

        private static System.Data.DataTable ExecStoredProc(string cs, string spName,
            params MySqlParameter[] spParams)
        {
            using MySqlConnection connection = new MySqlConnection(cs);
            using MySqlCommand command = new MySqlCommand(spName, connection);
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.AddRange(spParams);
            connection.Open();
            DataTable dt = new DataTable();
            dt.Load(command.ExecuteReader());
            return dt;
        }
    }
}

重新创建测试数据库和表的几行代码:

CREATE SCHEMA `test` DEFAULT CHARACTER SET latin1 COLLATE latin1_general_ci ;
use test;
CREATE TABLE `test`.`test` (
  `k` VARCHAR(64) NOT NULL,
  `v` VARCHAR(64) NULL,
  PRIMARY KEY (`k`));
INSERT INTO test.test (k,v) values ('KA','VA');
DELIMITER $$
CREATE PROCEDURE `GetValue`(par0 varchar(64))
BEGIN
select * from test.test where k = par0;
END$$
DELIMITER ;

提前谢谢你-

【问题讨论】:

  • 看起来您在 F# 中创建的参数与 C# 不同。你试过用同样的方法吗?
  • Fyodor,在 C# 和 F# 方面,我对 command.Parameters.AddWithValue("par0", "KA") 进行了硬编码。 C# 通过,F# 失败。我还检查了是否触发了预期的 mysql 服务器、数据库和存储过程。
  • 在您发布的C#代码中,我可以清楚地看到参数是通过AddRange而不是AddWithValue添加的

标签: f# .net-core-3.1


【解决方案1】:

简单:这是做什么的?

command.CommandType = CommandType.StoredProcedure |> ignore

它只是比较了 2 个值。

应该是:

command.CommandType <- CommandType.StoredProcedure |> ignore

【讨论】:

    猜你喜欢
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2013-06-17
    相关资源
    最近更新 更多