2013-10-21 80 views
-2

我有這樣一個存儲過程:存儲過程總是把第一個參數從代碼

ALTER PROCEDURE [dbo].[T_TransactionSummary] 
@locations nvarchar 
AS 
    BEGIN 
.............. 
............. 
AND (Location_tbl.Locid IN (@locations)) 

我LOCID字段是整數 這LOCID從我listbox.if未來我選擇一個項目1 LOCID會來。如果我選擇2項2 LOCID會來.. 我有它填充@locations參數(整數)的列表框,我把我的列表框的值這樣的

cnt = LSTlocations.SelectedItems.Count 
Dim list As New List(Of Integer) 
     Dim locid As Integer 
     If cnt > 0 Then 
      For i = 0 To cnt - 1 
       Dim locationanme As String = LSTlocations.SelectedItems(i).ToString 
       locid = RecordID("Locid", "Location_tbl", "LocName", locationanme) 
       list.Add(locid) 
      Next 
End If 
Dim da As New SqlDataAdapter 
     Dim ds As New DataSet 
     Dim cmd23 As New SqlCommand("T_TransactionSummary", con.connect) 
     cmd23.CommandType = CommandType.StoredProcedure 
     cmd23.Parameters.Add("@locations", SqlDbType.Int).Value = String.Join(",", list) 
     da.SelectCommand = cmd23 
     da.Fill(ds) 

現在從列表框中我locationid在流逝僅存儲過程1,2,3 。但存儲過程總是取第一個值(我的意思是在這種情況下取​​1)。

+0

您是否首先執行了任何簡單的調試?像'PRINT @locations;'? –

+0

不,先生...爲什麼我必須這樣做? – user2878851

+0

因爲在這種情況下,它會顯示您傳遞的值正在被截斷。 –

回答

1

以下是第一個問題。

cmd23.Parameters.Add("@locations", SqlDbType.Int).Value = String.Join(",", list) 

您正在將@locations參數添加爲int。當你給它賦值時VB會將你的字符串轉換爲一個int。這意味着"1,2,3,4"將變爲"1"

改變,要一個SqlDbType.VarChar


至於第二個,我不完全相信你可以這樣做:

AND (Location_tbl.Locid IN (@locations)) 

你可能想看看錶值參數。

+0

我如何處理表值參數....我是新概念 – user2878851

+0

@ user2878851:看看亞倫的答案。他告訴你將sp參數更改爲'@locations dbo.Integers READONLY'的部分是TVP。 – NotMe

+0

我只是在我的存儲過程中給出這樣的:@locations整數只讀..現在我得到錯誤:參數「@locations」不能被聲明爲READONLY,因爲它不是一個表值參數。 – user2878851

7

首先,you absolutely need to define a length for your parameter ...您當前擁有的是在第一個字符處被截斷的字符串。

​​

結果:

1 

你需要說

@locations VARCHAR(MAX) 

你不需要NVARCHAR存儲一個逗號分隔的整數列表。 (我假設你可能有一個整數一個長長的清單,但或許MAX可能是8000代替。)

然後,你不能說IN (@locations) - 這將無法正常工作,要麼你將獲得有關轉換'1,2,3...'的錯誤消息到一個int,或者它只是不會找到值 - 這是比較整個字符串,而不是集合。所以你可以用動態SQL來做到這一點,例如

SET @sql = @sql + ' WHERE locations IN (' + @locations + ') ...;'; 

但是,這充滿了各種其他問題,包括可維護性和SQL注入風險。我強烈推薦使用表值參數。基本上你創建一個類型是這樣的:

CREATE TYPE dbo.Integers AS TABLE(Item INT PRIMARY KEY); 

然後你使用的參數是這樣的:

@locations dbo.Integers READONLY 

你可以說:

WHERE EXISTS (SELECT 1 FROM @locations WHERE Item = Location_tbl.Locid) 

在您的VB.Net代碼,你將您的列表框選擇填充到DataTable(而不是int或字符串)中,並將DataTable作爲參數傳遞給SqlDbType.Structured。我有一些例子在這裏,但他們是C#:

http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql

還有plenty of documentation on TVPs on MSDN

+0

先生..我必須改變..? – user2878851

+0

+1這個答案太長了。 – Kermit

+1

@ user2878851我想我已經在這裏給出了非常透徹和有用的說明。 –

相關問題