2012-04-09 160 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

相關問題