2017-08-25 20 views
1

SQL Server 2012データベースでvb.netを使用しています。vb.netを使用してSQLクエリの入力としてリストを渡すベストプラクティス

データベース内のファイルのリストのステータスを確認したいとします。クエリはシンプルで、このようなものです。

DECLARE @Filename NVARCHAR(100) 

SET @Filename = 'MyFileName.doc' 

SELECT DISTINCT 
    Docs.Filename, 
    Status.Name as 'Status' 
FROM 
    [Documents] AS Docs 
INNER JOIN 
    [Status] AS Status ON Status.StatusID = Docs.CurrentStatusID 
WHERE 
    Docs.Filename LIKE @Filename 

これは1つのファイル名で正常に動作し、この例のようにSQL接続を使用してvb.netで簡単に起動できます。

Dim conn As New SqlConnection 
If conn.State = ConnectionState.Closed Then 
    conn.ConnectionString = PDMConnectionString 
End If 

Try 
    conn.Open() 
    Dim sqlquery As String = 
     "DECLARE @Filename NVARCHAR(100) 
     SELECT DISTINCT 
     Docs.Filename, 
     Status.Name as 'Status' 

     FROM [Documents] AS Docs 
     INNER JOIN [Status] AS Status 
     ON Status.StatusID = Docs.CurrentStatusID 

     WHERE Docs.Filename LIKE @Filename " 

    Dim data As SqlDataReader 
    Dim adapter As New SqlDataAdapter 
    Dim parameter As New SqlParameter 
    Dim command As SqlCommand = New SqlCommand(sqlquery, conn) 
    With command.Parameters 
     .Add(New SqlParameter("@filename", "MyFileName.doc")) 
    End With 
    command.Connection = conn 
    adapter.SelectCommand = command 
    data = command.ExecuteReader() 
    While data.Read 
     'do something' 
    End While 
Catch ex As Exception 

End Try 

問題は、たくさんのファイルの状態を調べる必要があるため、1つのクエリで処理したいと思っています。

私は、このような最後の行を変更vb.netでパラメータを削除し、直接クエリを送信することによりにより、クエリで直接それを行うことができます。

WHERE 
    Docs.Filename IN ('MyFileName.doc', 'MyOtherFileName.doc') 

しかし、それは文字列連結の多くを意味し、私はコードがその解決策のように見えるのは本当に好きではありません。

少ない文字列連結を使用して管理しやすいコードを作成するために、このような状況で使用するベストプラクティスは何ですか?

CREATE FUNCTION [dbo].[FileNames](@FilenameValues nvarchar(max)) 
RETURNS @Result TABLE(FileName nvarchar(max)) 
AS 
BEGIN 

     -- convert to an xml string 
     DECLARE @xml XML 
     SELECT @xml = CAST('<A>' + REPLACE(@FilenameValues, ',', '</A><A>') + '</A>' AS XML) 

     -- select rows out of the xml string 
     INSERT INTO @Result    
     SELECT DISTINCT LTRIM(RTRIM(t.value('.', 'nvarchar(max)'))) AS [FileName] 
     FROM @xml.nodes('/A ') AS x(t) 

     RETURN 

    END 

は、その後、あなたのSQLのいずれかでそれを登録しようあなたは、カンマ区切りの文字列を取り、テーブルを返すように関数を使用することができ
+0

@Magnus、あなたの提案は重複のために "間違った"解決策を持っています。正しいアプローチはテーブル値のパラメータになります – Fabio

+0

"たくさんの文字列連結"が意味することに依存します。Linqはほんの数行でそのようなことをすることができます。私は、たとえSQLストアドプロシージャから選択したXMLリストであっても、SQL Serverが配列としてパラメータを許可するかどうかを確認したい – Plutonix

答えて

0

... ...

JOIN (
    SELECT * FROM dbo.FileNames('MyFileName.doc, MyOtherFileName.doc') 
) FileNames ON FileNames.FileName = Docs.Filename 

ORで使用どこに...

WHERE Docs.Filename IN( 
    SELECT * FROM dbo.FileNames('MyFileName.doc, MyOtherFileName.doc') 
) 
関連する問題