首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >C# SQL Server -将列表传递给存储过程

C# SQL Server -将列表传递给存储过程
EN

Stack Overflow用户
提问于 2011-08-18 01:40:34
回答 8查看 201K关注 0票数 118

我正在从我的C#代码中调用SQL Server存储过程:

代码语言:javascript
复制
using (SqlConnection conn = new SqlConnection(connstring))
{
   conn.Open();
   using (SqlCommand cmd = new SqlCommand("InsertQuerySPROC", conn))
   {
      cmd.CommandType = CommandType.StoredProcedure;

      var STableParameter = cmd.Parameters.AddWithValue("@QueryTable", QueryTable);
      var NDistanceParameter = cmd.Parameters.AddWithValue("@NDistanceThreshold", NDistanceThreshold);
      var RDistanceParameter = cmd.Parameters.AddWithValue(@"RDistanceThreshold", RDistanceThreshold);

      STableParameter .SqlDbType = SqlDbType.Structured;
      NDistanceParameter.SqlDbType = SqlDbType.Int;
      RDistanceParameter.SqlDbType = SqlDbType.Int;

      // Execute the query
      SqlDataReader QueryReader = cmd.ExecuteReader();

我的存储进程是相当标准的,但是使用QueryTable进行连接(因此需要使用存储进程)。

现在:我想向参数集中添加一个字符串列表List<string>。例如,我存储的proc查询是这样的:

代码语言:javascript
复制
SELECT feature 
FROM table1 t1 
INNER JOIN @QueryTable t2 ON t1.fid = t2.fid 
WHERE title IN <LIST_OF_STRINGS_GOES_HERE>

但是,字符串列表是动态的,并且有几百个长度。

有没有办法把 List<string> 的字符串列表传递给存储的proc?,或者有没有更好的方法呢?

非常感谢,布雷特

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-08-18 01:52:25

如果您使用的是SQL Server2008,则会有一个称为用户定义表类型的新功能。下面是一个如何使用它的示例:

创建用户定义的表类型:

代码语言:javascript
复制
CREATE TYPE [dbo].[StringList] AS TABLE(
    [Item] [NVARCHAR](MAX) NULL
);

接下来,您需要在存储过程中正确使用它:

代码语言:javascript
复制
CREATE PROCEDURE [dbo].[sp_UseStringList]
    @list StringList READONLY
AS
BEGIN
    -- Just return the items we passed in
    SELECT l.Item FROM @list l;
END

最后,下面是在c#中使用它的一些sql:

代码语言:javascript
复制
using (var con = new SqlConnection(connstring))
{
    con.Open();

    using (SqlCommand cmd = new SqlCommand("exec sp_UseStringList @list", con))
    {
        using (var table = new DataTable()) {
          table.Columns.Add("Item", typeof(string));

          for (int i = 0; i < 10; i++)
            table.Rows.Add("Item " + i.ToString());

          var pList = new SqlParameter("@list", SqlDbType.Structured);
          pList.TypeName = "dbo.StringList";
          pList.Value = table;

          cmd.Parameters.Add(pList);

          using (var dr = cmd.ExecuteReader())
          {
            while (dr.Read())
                Console.WriteLine(dr["Item"].ToString());
          }
         }
    }
}

要从SSMS执行此操作,请执行以下操作

代码语言:javascript
复制
DECLARE @list AS StringList

INSERT INTO @list VALUES ('Apple')
INSERT INTO @list VALUES ('Banana')
INSERT INTO @list VALUES ('Orange')

-- Alternatively, you can populate @list with an INSERT-SELECT
INSERT INTO @list
   SELECT Name FROM Fruits

EXEC sp_UseStringList @list
票数 192
EN

Stack Overflow用户

发布于 2011-08-18 01:45:32

这种情况下的典型模式是传递逗号分隔列表中的元素,然后在SQL中将其拆分成可以使用的表。大多数人通常会创建一个特定的函数来执行此操作,如下所示:

代码语言:javascript
复制
 INSERT INTO <SomeTempTable>
 SELECT item FROM dbo.SplitCommaString(@myParameter)

然后您可以在其他查询中使用它。

票数 24
EN

Stack Overflow用户

发布于 2011-08-18 02:09:20

不能,数组/列表不能直接传递到SQL Server。

以下选项可用:

  1. 传递一个逗号分隔的列表,然后在SQL中使用一个函数拆分该列表。逗号分隔的列表最有可能作为SQL传递,并且在SQL Server中有一个函数为列表中的每个值解析Nvarchar()
  2. Pass,并使用新定义的用户定义的表类型(SQL 2008)
  3. Dynamically构建

,并以"1,2,3,4“的形式传入原始列表,然后构建

  1. 语句。这很容易受到SQL注入攻击,但它会起作用。
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7097079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档