MSSQL 存储过程未正确读取参数

MSSQL Stored Procedure not reading parameter correctly

我是 learning/building AWS RDS/Lambda/API 网关的 API。数据库是 MSSQL,因为我们过去一直使用 SQL 数据库,而 Lambda 是在 Visual Studio.

中用 C# 编写的(我也是 C# 的新手)

我已经用一个简单的虚拟用户 table 设置了一个测试数据库,并编写了一个基本的 SP 来获取数据。 SP 采用单个可选参数 'User' 和 returns 找到该用户的所有列,如果没有发出参数则为所有列。

在 MSSMS 中进行了测试,SP 在有参数和无参数的情况下都能正常工作。我已经在 Visual Studio 中编写了函数,并使用 Mock Lambda 测试工具进行了测试。如果没有发送参数,那么我会得到一个完整的用户列表。但是,当我尝试传递参数时,reader 执行但 returns 没有结果。我已经检查并三次检查了参数名称和值,两者都应该有效。我不明白为什么会这样?我已经在 VB.net 中这样做了数千次,从来没有遇到过问题。

代码如下:

SP:

USE [playground]
GO
/****** Object:  StoredProcedure [dbo].[GetUsers]    Script Date: 22/02/2021 14:29:09 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[GetUsers]

    @User varchar(60) = null

AS

BEGIN

    SELECT * 
    FROM PlayUsers
    WHERE (@User IS NULL OR UName = @User)

END

C#代码:

public static class Function
    {
        /// <summary>
        /// Run a simple SP with optinal parameter to prove concept
        /// </summary>
        public static object FunctionHandler(ILambdaContext context)
        {
            var users = "";
            Console.WriteLine("*** Starting function ***");
            try
            {

                using (SqlConnection conn = new SqlConnection(GetConnectionString()))
                {
                    
                    SqlCommand cmd = new SqlCommand("GetUsers", conn)
                    {
                        CommandType = CommandType.StoredProcedure
                    };
                    cmd.Parameters.AddWithValue("@User", "BearDown");
                    //cmd.Parameters.Add("@User", SqlDbType.VarChar).Value = "BearDown";

                    conn.Open();

                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            users += ToJson(rdr);
                        }
                    }

                    conn.Close();
                    cmd.Dispose();
                    conn.Dispose();
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception thrown: {ex}");
            }
            finally
            {
                Console.WriteLine("*** End function  ***");
            }

            return users;
        }

        public static string ToJson(this SqlDataReader rdr)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            using (JsonWriter jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.WriteStartArray();

                while (rdr.Read())
                {
                    jsonWriter.WriteStartObject();

                    int fields = rdr.FieldCount;

                    for (int i = 0; i < fields; i++)
                    {
                        jsonWriter.WritePropertyName(rdr.GetName(i));
                        jsonWriter.WriteValue(rdr[i]);
                    }

                    jsonWriter.WriteEndObject();
                }

                jsonWriter.WriteEndArray();

                return sw.ToString();
            }
        }
    }

如您所见,我尝试了 .Add 和 .AddWithValue 来添加参数,但似乎都没有传递参数。我已经逐步检查了代码,可以看到它通过 SQL Reader 执行 运行 并且没有异常命中,但它从未找到任何结果。

将监视添加到 rdr 它显示:使用参数时“枚举未产生任何结果”。但同样,在 MSSMS 中执行 SP 时,这两个值都可以正常工作。

** 更新 ** 在解决这个问题之后,我发现替换

using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            users = rdr.ToJson();
                        }
                    }

只有

                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                      users = rdr.ToJson();
                    }

按要求工作。我想我会把它包装在一个 if (rdr.HasRows) 中,看起来像是一个解决方案。

您在 FunctionHandler 中调用 rdr.Read()(“将 reader 推进到下一条记录”),然后在您从那里调用的 ToJson 函数中再次调用...我不认为这是预期的行为?你总是在那里跳过一条记录......我的建议是尝试在 FunctionHandler.

中不使用 rer.Read()