2017-06-16 49 views
2

我有一些SQL通過盲目需求/請求轉換爲存儲過程。在我看到的應用程序中有一點SQL使用動態IN(set)語句構建where子句。我已經搜索了動態存儲過程,但沒有接近我正在尋找的東西對我來說。這裏是WHERE子句的示例:如何使用動態創建的IN集創建存儲過程

WHERE Var.A = @Param AND Var.Id IN 

從這裏SQL是使用字符串生成器手動構建的,然後執行。不知道如何將它轉換爲存儲過程,因爲我對它們相當陌生。

我們正在使用C#和SQL Server

+2

如何將用戶定義的表格類型從C#發送到proc? – hardkoded

+0

這聽起來不錯。但我不知道這意味着什麼。我會研究這個角度。謝謝大聲笑 – Matt1776

+0

@ Matt1776:根據各種因素,IN子句可以是從良性到病態的不良表現。由於IN子句的目的是過濾返回的行,INNER JOIN子句也是這樣做的(除了引入額外的列之外),執行INNER JOIN而不是IN會比較好,而且往往會更好。 (回想一下,INNER JOIN只返回兩個表中匹配連接字段的行。) –

回答

3

您可以使用用戶定義的數據類型。

在C#方面,它應該是這樣的:

//Setup a DataTable with the same structure as the SQL Type 
var data = new DataTable(); 
data.Columns.Add("value", typeof(string)); 

//Populate the table 
data.Rows.Add("oneID"); 
data.Rows.Add("anotherID"); 

//You create your sql command 
cmd.Parameters.Add("@listArgument", data); 
//Command execution 

SQL一邊,你可以有一種這樣的

CREATE TYPE [dbo].[NVarCharTable] AS TABLE (
    [value] NVARCHAR(MAX) NOT NULL); 

然後存儲過程:

CREATE PROCEDURE [dbo].[MyProc] 
    @listArgument NVarCharTable READONLY 
AS 
BEGIN 

    SELECT * 
    FROM FOO 
    WHERE Var.Id IN (Select [value] FROM @listArgument) 

END 

參考:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters

+0

這是......很美。這看起來類似於創建臨時視圖,但這被稱爲用戶定義的表類型?我會看看這是否有效! – Matt1776

+1

我已經添加了一個引用鏈接來閱讀,我使用DataTables,但有很多方法使用它從C# – hardkoded

+0

我有一個時間讓這個工作老實說 - 這絕對是由於我缺乏經驗用這種方法。當我在SQL Server中執行存儲過程時,如何設置[NVarCharTable]的值?它只給我一個窗口界面,我不能寫SQL – Matt1776

1

如果您使用的是SQl SERVER 2016或更高版本,則可以使用string_split函數將csv參數轉換爲表格,然後將其用於您的IN列表中。

SELECT * FROM TBL WHERE Var.A = @Param AND Var.Id IN (SELECT value FROM STRING_SPLIT(@inlist, ',')) 

希望這有助於

+0

唉,我們被鎖定到SQLServer 2012,但是這看起來像一個有效的,更簡單的選項,因爲split會返回一個表。嘗試一下會很好。 – Matt1776

+0

有那麼多的函數需要一個值列表並分解到一個表中。只是Google它 - sql server central至少有3個版本。所以這種方法在其他版本中也是可行的,只需要添加1個函數。 – Jesse

+0

@Jesse經過一些粗略的研究我只找到一種方法來創建一個調用dll的函數 - 你有什麼具體的想法嗎?仔細閱讀SQLServer文檔後,我沒有看到任何可以使用的東西,這不會太繁重。 – Matt1776