【问题标题】:Pass GUID into stored procedure method C#将 GUID 传递到存储过程方法 C#
【发布时间】:2020-06-26 13:57:10
【问题描述】:

我大多是 C# 新手,所以我在这里寻找一些指导。我正在测试一种方法,我需要将一个 guid 列表传递给并运行一个存储过程,该过程根据我传递给它的 guid 返回值,然后我可以打印到控制台。当我只传递一个 guid 时,我可以让该方法工作,但是当我传递一个 guid 列表时,它似乎不起作用。

我觉得我对如何传递 guid 列表并返回它缺乏一些了解。我在尝试返回 List 时遇到转换错误。

这是我已经走了多远,但我觉得我现在被卡住了,无法从我在网上找到的任何信息中取得进展。

class Program
{
    static void Main(string[] args)
    {
        List<Guid> tempguid = new List<Guid>();
        tempguid.Add(Guid.Parse("472USFA0-B705-9A73-ABD4-3B1870AF1409"));
        tempguid.Add(Guid.Parse("FA97E6BB-0875-5UB9-967A-87ECC396F9F0"));

        GetValue(tempguid);
        Console.WriteLine(GetValue);
    }

    public void GetValue(List<Guid> tempguid)
    {
        using (SqlConnection conn = new SqlConnection("connection string here"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand("stored procedure here", conn);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@id", tempguid));

            using (SqlDataReader rdr = cmd.ExecuteReader())
            {
                while (rdr.Read())
                {
                    Console.WriteLine((string)rdr["value"]);
                }
                Console.ReadLine();
            }
        }
    }
}

我应该像 GetValue(List tempguid) 这样传递列表吗?

编辑

好吧,如果我使用 TVP。

类似:

CREATE TYPE [dbo].[Identity] AS TABLE(

[Id] [uniqueidentifier] NOT NULL
)
GO

然后我的程序将类似于以下内容:

CREATE OR ALTER PROCEDURE [dbo].[procedure_name]
@id dbo.Identity READONLY
as
SELECT t.[id]
      ,t.[value]
  FROM [dbo].[table1] t
  Inner Join @id i on i.Id = t.id

如何在 c# 中将此 TVP 用于我的存储过程?

【问题讨论】:

  • 一种方法是使用 TVP - docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/… 将多个值传递给存储过程。这里有一个例子 - stackoverflow.com/questions/62301581/…
  • 存储过程是什么样的(不是过程本身(如果它很复杂),主要是 CREATE 和参数部分)。正如@mahesh_b 所指出的,您可能希望传递一个表值参数。
  • @Flydog57 存储过程中唯一的参数是id
  • 而且,ID 被键入为 ... ?
  • 嘿,@Flydog57 我刚刚使用 TVP 对我的问题进行了编辑。然后我如何使用它来传递 c# 中的 guid 列表?

标签: c# sql sql-server stored-procedures


【解决方案1】:

您需要在 GUID 列表上使用 foreach 循环。试试看:

foreach (var g in tempguid)
{
    cmd.Parameters.Add(new SqlParameter("@id", g));
    using (SqlDataReader rdr = cmd.ExecuteReader())
    {
       while (rdr.Read())
       {
          Console.WriteLine((string)rdr["value"]);
       }
       Console.ReadLine();
    }
    cmd.Parameteres.Clear();
}

【讨论】:

    【解决方案2】:

    您不能将列表传递给 sp。您需要将您的 guid 转换为 csv 字符串示例:

    var param = string.Join(", ", tempguid);
    

    然后

    cmd.Parameters.Add(new SqlParameter("@id", param));
    

    然后在接收到你的参数后将 sp 传入String_Split。祝你好运!

    【讨论】:

    • 您可以传递一个列表 - 作为一个表值参数。如果你还是要修改这个过程,不如把它做对,而不是拆分字符串。
    【解决方案3】:

    从 ADO .NET 将值传递给 TVPs 非常简单,与将数据传递给常规参数相比,只需要很少的额外代码。

    • 对于您指定的数据类型 SqlDbType.Structured。
    • 您在参数的 TypeName 属性中指定表类型的名称。
    • 您将参数的 Value 属性设置为合适的值。

    如上面链接中提到的System.Data.SqlClient 支持从DataTableDbDataReaderIEnumerable&lt;T&gt; \ SqlDataRecord 对象填充表值参数。

    如果您的案例tempguid 中已经有来自其他来源的Guid 列表,那么您可以使用datatable 将详细信息传递给存储过程。

    DataTable tvp = new DataTable();
    tvp.Columns.Add(new DataColumn("Id", typeof(Guid)));
    
    // populate DataTable from your List here
    foreach (var id in tempguid)
       tvp.Rows.Add(id);
    

    并像下面这样更改 ADO.NET 代码 -

    conn.Open();
    SqlCommand cmd = new SqlCommand("dbo.tvpProcedure", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvpParameter = new SqlParameter();
    tvpParameter.ParameterName = "@id";
    tvpParameter.SqlDbType = System.Data.SqlDbType.Structured;
    tvpParameter.Value = tvp;
    tvpParameter.TypeName = "dbo.testTVP";
    cmd.Parameters.Add(tvpParameter);
    
     using (SqlDataReader rdr = cmd.ExecuteReader())
       {
         while (rdr.Read())
          {
            Console.WriteLine((string)rdr["value"]);
          }
           Console.ReadLine();
        }
    

    旁注:

    • 看起来您在代码中显示的GUIDs 似乎无效,因为它们包含非 十六进制值。

      472USFA0-B705-9A73-ABD4-3B1870AF1409
         ^^
      FA97E6BB-0875-5UB9-967A-87ECC396F9F0
                     ^
      
    • 在我使用的情况下,将类型名称更改为有意义的而不是 dbo.Identity dbo.testTVP

    更多信息 -

    http://www.sommarskog.se/arrays-in-sql-2008.html

    【讨论】:

    • 是的,这很有帮助,谢谢。我的另一个主要问题是如何将列表传递给一个方法,然后返回存储过程结果。
    • 您已经将列表传递给方法 - GetValue(tempguid); Console.WriteLine(GetValue);,但是您的控制台正在打印方法名称,因此将这两行更改为 Console.WriteLine(GetValue(tempguid));或者只是调用该方法,因为该方法正在打印值。希望这就是您所指的!
    • Console.WriteLine(GetValue);这根本不需要!
    • 是的,对不起,我现在把这一切都解决了。感谢您的帮助
    • 如果答案对您有帮助,我们很高兴:)
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2021-04-28
    • 2012-05-08
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    相关资源
    最近更新 更多