变量名称在查询批处理或存储过程中必须唯一

比昂·罗格·克林佐(Bjørn-RogerKringsjå)

我正在尝试实现一个异步搜索“引擎”,但是我遇到了一些困难。

由于某种原因,偶尔会抛出一次SqlException,表明:

“变量名称'@input'已经声明。变量名称在查询批处理或存储过程中必须是唯一的。”

样品申请

样品申请

以下代码以sys.messages为目标,因此您要做的就是更改连接字符串

Public Class Form1

    Public Sub New()
        Me.InitializeComponent()
        Me.input = New TextBox() With {.Dock = DockStyle.Top, .TabIndex = 0}
        Me.output = New RichTextBox() With {.Dock = DockStyle.Fill, .TabIndex = 1, .ReadOnly = True, .WordWrap = False}
        Me.Controls.AddRange({Me.output, Me.input})
    End Sub

    Private Sub Search(sender As Object, e As EventArgs) Handles input.TextChanged
        Dim input As String = Me.input.Text
        Static command As SqlCommand
        Static source As CancellationTokenSource
        If (Not command Is Nothing) Then command.Cancel()
        If (Not source Is Nothing) Then source.Cancel()
        command = New SqlCommand()
        source = New CancellationTokenSource()
        Task.Factory.StartNew(Sub() Me.SearchingAsync(input, command, source.Token))
    End Sub

    Private Sub SearchingAsync(input As String, command As SqlCommand, token As CancellationToken)
        Dim [error] As Exception = Nothing
        Dim cancelled As Boolean = False
        Dim result As List(Of sys_message) = Nothing
        Try
            Using connection As New SqlConnection("Server=instance\name;Database=name;Trusted_Connection=True;")
                connection.Open()
                command.Connection = connection
                command.CommandType = CommandType.Text
                command.CommandText = "select * from sys.messages where [text] like '%' + @input + '%';"
                command.Parameters.AddWithValue("@input", input)
                Using reader As SqlDataReader = command.ExecuteReader()
                    result = New List(Of sys_message)()
                    Do While (reader.Read() AndAlso (Not token.IsCancellationRequested))
                        result.Add(New sys_message() With {
                            .message_id = CInt(reader.Item("message_id")),
                            .language_id = CInt(reader.Item("language_id")),
                            .severity = CInt(reader.Item("severity")),
                            .is_event_logged = CBool(reader.Item("is_event_logged")),
                            .text = CStr(reader.Item("text"))
                        })
                    Loop
                End Using
            End Using
            cancelled = token.IsCancellationRequested
        Catch ex As SqlException When ex.Message.ToLower().Contains("operation cancelled by user")
            cancelled = True
        Catch ex As ThreadAbortException
            cancelled = True
        Catch ex As OperationCanceledException
            cancelled = True
        Catch ex As Exception
            [error] = ex
        Finally
            Me.Invoke(
                Sub()
                    'If (String.CompareOrdinal(input, Me.input.Text) = 0) Then
                    If (Not [error] Is Nothing) Then
                        Me.output.Text = String.Concat("Input='", input, "', Output={Result: 'error', Type: '", [error].GetType.Name, "', Message: '", [error].Message.Replace(Environment.NewLine, " "), "'}", Environment.NewLine, Me.output.Text).Trim()
                    ElseIf (cancelled) Then
                        Me.output.Text = String.Concat("Input='", input, "', Output={Result: 'cancelled'}", Environment.NewLine, Me.output.Text).Trim()
                    Else
                        Me.output.Text = String.Concat("Input='", input, "', Output={Result: 'success', Count: ", result.Count, "}", Environment.NewLine, Me.output.Text).Trim()
                    End If
                    'End If
                End Sub
            )
        End Try
    End Sub

    Private WithEvents input As TextBox
    Private WithEvents output As RichTextBox

    Private Class sys_message
        Public message_id As Integer
        Public language_id As Integer
        Public severity As Integer
        Public is_event_logged As Boolean
        Public text As String
    End Class

End Class
Damien_The_Unbeliever

因为您无意间SqlCommand在多次调用之间共享对象SearchingAsync我将删除试图处理这些外部代码的外部代码,而仅SearchingAsync创建其自己的未共享实例。

同时,您可能要考虑使用SqlCommand公开的异步API ,例如ExecuteReaderAsync,它允许您将取消令牌传递给他们,以便所有取消都由您的单个取消令牌处理。

您还需要确保将正确的取消令牌传递给方法的正确调用:

Private Sub Search(sender As Object, e As EventArgs) Handles input.TextChanged
    Dim input As String = Me.input.Text
    Static source As CancellationTokenSource
    If (Not source Is Nothing) Then source.Cancel()
    source = New CancellationTokenSource()
    Dim token = source.Token
    Task.Factory.StartNew(Sub() Me.SearchingAsync(input, token))
End Sub

基本上,在这一行代码中:

Task.Factory.StartNew(Sub() Me.SearchingAsync(input, command, source.Token))

完成后,您所知道的就是,在将来的某个时间点,它将执行以下操作:

Me.SearchingAsync(input, command, source.Token)

在将来的那个时间点,它将SqlCommandcommand变量中加载一个对象,然后调用SearchingAsync(并且类似地,source在此时加载)

但是,如果与此同时您的Search方法又重新运行怎么办?它取消了commandsource最初用于此方法调用的,并将其替换为新副本。并且计划在将来运行另一个任务SearchingAsync这两个调用最终引用了相同的command对象,因此最终@input给它添加了两次参数。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

变量名“ @ArrivedDate”已经声明。变量名称在查询批处理或存储过程中必须唯一

来自分类Dev

'变量名'@'已经被声明。在查询批处理或存储过程中,变量名必须唯一。

来自分类Dev

变量名“@Personnel_Number”已被声明。变量名在查询批处理或存储过程中必须是唯一的

来自分类Dev

在重复过程中构建AngularJS变量名称

来自分类Dev

必须声明存储过程中的标量变量错误

来自分类Dev

批处理文件:如何使用已经存储在字符串中的变量名称获取变量的值

来自分类Dev

SQL设置变量作为存储过程中查询的结果

来自分类Dev

SQL设置变量作为存储过程中查询的结果

来自分类Dev

CREATE VIEW必须是批处理中唯一的语句

来自分类Dev

create函数必须是批处理中的唯一语句

来自分类Dev

JS中的非唯一变量名称

来自分类Dev

Sql 在存储过程中声明一个变量

来自分类Dev

如何从DB2上的COBOL存储过程中调用COBOL批处理程序

来自分类Dev

将变量添加到批处理过程中

来自分类Dev

如何将查询结果存储在MySql存储过程中的变量中

来自分类Dev

存储过程中的Oracle查询

来自分类Dev

PostgreSQL存储过程中的相同查询

来自分类Dev

关于存储过程中的查询

来自分类Dev

存储过程中的SQL查询IF语句

来自分类Dev

更新MYSQL存储过程中的查询

来自分类Dev

在迭代过程中获取变量的名称

来自分类Dev

Oracle存储过程中的表变量

来自分类Dev

无法在存储过程中声明变量

来自分类Dev

在mysql存储过程中声明变量

来自分类Dev

存储过程中的变量声明

来自分类Dev

如何在存储过程中编写带有动态表名称的Select查询?

来自分类Dev

在存储过程中创建唯一ID以匹配旧数据

来自分类Dev

在存储过程中创建唯一ID以匹配旧数据

来自分类Dev

数据库名称为变量-存储过程中的动态SQL

Related 相关文章

  1. 1

    变量名“ @ArrivedDate”已经声明。变量名称在查询批处理或存储过程中必须唯一

  2. 2

    '变量名'@'已经被声明。在查询批处理或存储过程中,变量名必须唯一。

  3. 3

    变量名“@Personnel_Number”已被声明。变量名在查询批处理或存储过程中必须是唯一的

  4. 4

    在重复过程中构建AngularJS变量名称

  5. 5

    必须声明存储过程中的标量变量错误

  6. 6

    批处理文件:如何使用已经存储在字符串中的变量名称获取变量的值

  7. 7

    SQL设置变量作为存储过程中查询的结果

  8. 8

    SQL设置变量作为存储过程中查询的结果

  9. 9

    CREATE VIEW必须是批处理中唯一的语句

  10. 10

    create函数必须是批处理中的唯一语句

  11. 11

    JS中的非唯一变量名称

  12. 12

    Sql 在存储过程中声明一个变量

  13. 13

    如何从DB2上的COBOL存储过程中调用COBOL批处理程序

  14. 14

    将变量添加到批处理过程中

  15. 15

    如何将查询结果存储在MySql存储过程中的变量中

  16. 16

    存储过程中的Oracle查询

  17. 17

    PostgreSQL存储过程中的相同查询

  18. 18

    关于存储过程中的查询

  19. 19

    存储过程中的SQL查询IF语句

  20. 20

    更新MYSQL存储过程中的查询

  21. 21

    在迭代过程中获取变量的名称

  22. 22

    Oracle存储过程中的表变量

  23. 23

    无法在存储过程中声明变量

  24. 24

    在mysql存储过程中声明变量

  25. 25

    存储过程中的变量声明

  26. 26

    如何在存储过程中编写带有动态表名称的Select查询?

  27. 27

    在存储过程中创建唯一ID以匹配旧数据

  28. 28

    在存储过程中创建唯一ID以匹配旧数据

  29. 29

    数据库名称为变量-存储过程中的动态SQL

热门标签

归档