【问题标题】:How to pass a StringList as part of SqlParameter to obtain results from SqlServer如何将 StringList 作为 SqlParameter 的一部分传递以从 SqlServer 获取结果
【发布时间】:2015-09-12 18:48:21
【问题描述】:

我正在尝试通过将键列表作为 keycodelist 的参数传递来执行 sql 查询,但它不起作用。即使该值存在于数据库中,我也得到了 KeyNotFoundException。

我应该如何解决这个问题?是否需要转义调用getKeyValue的参数?

我这样调用函数。

getKeyValue("'username', 'userid'")


    private Function getKeyValue(ByVal keyList as String) 
          Dim output As Dictionary (Of String, String)
          Dim systemkeysql As String = "select key_code, key_value from system_key_table where key_code in (@keycodelist) "

                Try
                    Using connection As New SqlConnection(getConnectionString())
                        Using command As New SqlCommand(systemkeysql, connection)

                            With (command.Parameters)
                                .Add(New SqlParameter("@keycodelist", System.Data.SqlDbType.NVarChar)).Value = keylist
                            End With

                            connection.Open()
                            Using reader As SqlDataReader = command.ExecuteReader()
                                While reader.Read()
                                    output.Add(reader(0), reader(1))

                                End While
                            End Using

                        End Using
                        connection.Close()
                    End Using

                Catch ex As Exception
                    MsgBox(ex.Message, MsgBoxStyle.OkOnly)
                End Try 
        Return Output
End Function

【问题讨论】:

标签: sql-server vb.net


【解决方案1】:

我不喜欢“哦,我们以前有过这个,它是重复的”的一个原因是,链接的文章可能很旧,并且接受的答案和/或最高分的答案可能不是最好的今天... 这种方法也列在这些页面上,但得分很低。在我看来,这是处理这个问题的最快和最优雅的方法(至少对于像我这样的人来说,尽可能避免使用动态 SQL...)

DECLARE @tbl TABLE(ID INT, SomeValue VARCHAR(10));
INSERT INTO @tbl VALUES
 (1,'value 1')
,(2,'value 2')
,(3,'value 3')
,(4,'value 4')
,(5,'value 5');

DECLARE @ListOfIDs VARCHAR(20)='1,3,5';

WITH ListOfIDs AS
(
    SELECT CAST('<root><r>'+REPLACE(@ListOfIDs,',','</r><r>')+'</r></root>' AS XML) AS IDsAsXML
)
,ListOfIDsResolved AS
(
    SELECT x.y.value('.','int') AS ID
    FROM ListOfIDs
    CROSS APPLY ListOfIDs.IDsAsXML.nodes('/root/r') x(y)
)
SELECT * FROM @tbl AS tbl
INNER JOIN ListOfIDsResolved ON tbl.ID=ListOfIDsResolved.ID

【讨论】:

  • 那么,您宁愿将分隔值传递给数据库并拆分它们,而不是传递表值参数?优雅通常是见仁见智的问题,但最快的是可以测试的。是否愿意创建一个基准并将您的拆分技术与表值参数进行比较?
  • @ZoharPeled,好的,对不起我的措辞,这有点热情:-) 使用表值参数的方法也非常好。两者都会导致一个非常小的单值列表与(可能是索引的)表列之间的内部连接。 TVP 的拆分和开销都不会产生重大成本。我更喜欢不依赖于创建类型之类的结构的解决方案。我应该更清楚地将我的部分标记为意见......
  • 嗨 Zohar,还有一点:我刚刚发现@g5thomas 评论了他必须与 DBA 讨论的“创建权限”。这可能是更喜欢内联方法的原因。
  • 在没有权限创建类型的情况下,我可能会在 .net 代码中动态构建 sql 及其参数,而不是在 sql 中使用拆分器函数。我现在无法为此创建示例,可能需要几天时间。
猜你喜欢
  • 1970-01-01
  • 2015-05-02
  • 2010-09-06
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多