2012-04-09 154 views
3

我有一个字符串列表,我需要检查列表中的任何值是否包含在数据库表中。如果存在返回现有值的数据集。将列表<string>传递给存储过程

public DataSet CheckDocumentNumber(List<string> DocNumber) 
{ 
    DataSet DocNum = new DataSet(); 
    SqlTransaction transaction = DALDBConnection.SqlConnection.BeginTransaction(); 

    try 
    { 
     string[] taleNames = new string[1]; 
     taleNames[0] = "DocNum"; 
     SqlParameter[] param = new SqlParameter[1]; 
     param[0] = new SqlParameter("@DocNumber", DocNumber); 

     SqlHelper.FillDataset(transaction, CommandType.StoredProcedure, "spCheckDocNumber", DocNum, taleNames, param); 
     transaction.Commit(); 
    } 
    catch (Exception e) 
    { 
     transaction.Rollback(); 
    } 

    return DocNum; 
} 

我的存储过程是

CREATE PROCEDURE spCheckDocNumber 
    @DocNumber VARCHAR(MAX) 
AS 
BEGIN 
    SELECT * FROM tblDocumentHeader WHERE DocumentNumber = @DocNumber 
END 

我需要知道我怎么有列表传递到存储过程和如何与步骤检查清单。 PLZ帮助

+0

多少记录你期望的字符串变量可以有? – Pankaj 2012-04-09 14:41:50

+0

您是否可以控制存储过程,即是否允许更改它?您需要修改存储过程以使用表值参数(http://mindlesspassenger.wordpress.com/2011/05/09/table-valued-parameters-codefirst-and-stored-procedures-3/), xml,或者使用动态sql将列表包含到查询中。或者您将不得不为列表中的每个元素调用一次存储过程,这对于大型列表来说效率不高。 – mellamokb 2012-04-09 14:42:37

回答

6

Crate a Split函数根据char分割字符串。

GO 
CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(8000)) 
RETURNS table 
AS 
RETURN (
    WITH splitter_cte AS (
     SELECT CHARINDEX(@sep, @s) as pos, 0 as lastPos 
     UNION ALL 
     SELECT CHARINDEX(@sep, @s, pos + 1), pos 
     FROM splitter_cte 
     WHERE pos > 0 
    ) 
    SELECT SUBSTRING(@s, lastPos + 1, 
        case when pos = 0 then 80000 
        else pos - lastPos -1 end) as chunk 
    FROM splitter_cte 
) 
GO 

SELECT * 
    FROM dbo.Split(' ', 'the quick brown dog jumped over the lazy fox') 
OPTION(MAXRECURSION 0); 

然后使用Split函数,在一个逗号打破,那么你可以使用输出表,然后加入针对您所寻找的表格。

这可以使拆分逗号分隔列表非常容易。然后你可以传入一个字符串,所有的hte值都用逗号分隔。

希望这会有所帮助!

0

也许你可以在sql中使用In operator。关于如何在http://vyaskn.tripod.com/passing_arrays_to_stored_procedures.htm上使用此功能,还有一些教程。

+0

如何在数据库中的逗号分隔字符串值中操作IN谓词? – Pankaj 2012-04-09 14:44:25

+0

您将需要使用动态sql来完成此操作,但它绝对有可能。 – mellamokb 2012-04-09 14:44:44

+1

@Mellamokb OP需要先将集合传递给数据库。 – Pankaj 2012-04-09 14:45:39

0

发送XML到SQL

  List<string> lst = new List<string> { 
                 "1", 
                 "2", 
                 "3" 
               }; 

      XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
      namespaces.Add(string.Empty, string.Empty); 
      StringBuilder sb = new StringBuilder(); 
      using (var sw = new StringWriter(sb)) //serialize 
      { 
       var serializer = new XmlSerializer(typeof (List<string>)); 
       serializer.Serialize(sw, lst, namespaces); 
      } 

现在,发送到SB SQL作为PARAM。

这就是所有。

不使用CSV。

+0

不应该使用'SQlBulkCopy'吗?因此,发送数据库表中的所有记录并将其加入到您的存储过程中。最初在Parameters列表中发送一个唯一的GUID给Stored Proc,并在表中发送相同的GUID以跟踪关联的记录。一旦作业在Stored Proc中完成,只需在删除之前从表中删除关联的记录。你说什么 ? – Pankaj 2012-04-09 15:28:26

+0

我没有看到批量复制之间的任何关系。批量复制只是不保存在LOG文件中的插入。不要使用CSV值(像其他人所建议的那样)。使用通用格式:XML。 – 2012-04-09 17:26:32

1

您可以使用这样的代码: 这适用于SQL Server 2005中(或更高版本):

create procedure IGetAListOfStrings 
@List xml -- This will recevie a List of values 
    as 
begin 
    -- You can load then in a temp table or use it as a subquery: 
    create table #Values (ListValue nvarchar(20)); -- adjust nvarchar size 
    INSERT INTO #Values 
    SELECT DISTINCT params.p.value('.','varchar(20)') -- adjust nvarchar size 
    FROM @List.nodes('/params/p') as params(p); 
    ... 
end 

你必须调用与这样的参数此过程:

exec IGetAListOfValues 
@List = '<params> <p>string1</p> <p>string2</p> </params>' -- xml parameter 

的节点功能使用xPath表达式。在这种情况下,它是/params/p,因此XML使用<params>作为根,而<p>作为元素。

欲了解更多信息,请参阅本答案: Passing List of values to stored procedure

相关问题