Вставка переменных в строку запроса - это не сработает! - PullRequest
1 голос
/ 22 апреля 2010

В основном у меня есть строка запроса, когда я жестко закодировал в каталоге значение его хорошо. когда я пытаюсь добавить его через переменную, он просто не поднимается.

Это работает:

  Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=WaspTrackAsset_NROI;User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")

Это не так:

Public Sub GetWASPAcr()

    connection.Open()

    Dim dt As New DataTable()
    Dim username As String = HttpContext.Current.User.Identity.Name
    Dim sqlCmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = '" & username & "'", connection)

    Dim sqlDa As New SqlDataAdapter(sqlCmd)

    sqlDa.Fill(dt)

    If dt.Rows.Count > 0 Then

        For i As Integer = 0 To dt.Rows.Count - 1
            If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
                WASP = ""
            Else
                WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
            End If

        Next

    End If
    connection.Close()

End Sub

Dim WaspConnection As New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")

Когда я отлаживаю каталог пуст в строке запроса, но переменная WASP содержит значение «WaspTrackAsset_NROI»

Есть идеи, почему?

Приветствия

Джоунси

альтернативный текст http://www.freeimagehosting.net/uploads/ba8edc26a1.png

Ответы [ 6 ]

4 голосов
/ 28 апреля 2010

Я вижу несколько проблем.

  1. Вы используете конкатенацию в операторе SQL. Это плохая практика. Вместо этого используйте параметризованный запрос.
  2. Вы окружаете пароль одинарными кавычками. Они не нужны, и на самом деле, я удивлен, что это работает даже при условии, что сам пароль не имеет одинарных кавычек.
  3. Вы должны окружать классы, которые реализуют IDisposable, блоком Using
  4. Вы должны воссоздать объект соединения WASP в GetWASPcr следующим образом:
Public Sub GetWASPAcr()
    Dim username As String = HttpContext.Current.User.Identity.Name
    Dim listOfDatabaseConnectionString As String = "..."

    Using listOfDatabaseConnection As SqlConnection( listOfDatabaseConnectionString )
        Using cmd As New SqlCommand("SELECT WASPDatabase FROM dbo.aspnet_Users WHERE UserName = @Username")
            cmd.Parameters.AddWithValue( "@Username", username )

            Dim dt As New DataTable()
            Using da As New SqlDataAdapter( cmd )
                da.Fill( dt )

                If dt.Rows.Count = 0 Then
                    WaspConnection = Null
                Else
                    Dim connString As String = String.Format("Data Source=JURA;Initial Catalog={0};User Id={1};Password={2};" _ 
                        , dt.Rows(0)("WASPDatabase") _ 
                        , ConfigurationManager.AppSettings("WASPDBUserName") _ 
                        , ConfigurationManager.AppSettings("WASPDBPassword"))

                    WaspConnection = New SqlConnection(connString);
                End If  
            End Using
        End Using
    End Using
End Sub

В этом примере listOfDatabaseConnectionString - это начальная строка подключения к центральной базе данных, где он может найти имя каталога, которое следует использовать для последующих подключений.

Все это говорит, зачем вам нужна переменная уровня класса для хранения соединения? Вы должны сделать все ваши вызовы базы данных открыть соединение, сделать заявление SQL, закрыть соединение. Таким образом, пять вызовов базы данных открывают и закрывают соединение пять раз. Это звучит дорого, за исключением того, что .NET предоставляет вам пул подключений, поэтому, когда вы закончите с подключением, а другое будет запрошено, оно извлечет его из пула.

1 голос
/ 22 апреля 2010

Ваша строка, переданная в конструктор для этого объекта SqlConnection, будет оценена при создании экземпляра класса. Ваша переменная WASP (я предполагаю) не будет установлена ​​до тех пор, пока не будет вызван метод, который вы показали.

0 голосов
/ 28 апреля 2010

Проблема, как уже указывает Пэдди, в том, что объект WaspConnection инициализируется еще до того, как у вас появится возможность вызвать GetWASPAcr.Попробуйте это:

Public Sub GetWASPAcr()
   '[...]

End Sub

Dim _waspConnection As SqlConnection
Public Readonly Property WaspConnection As SqlConnection
  Get
    If _waspConnection Is Nothing Then
      GetWASPAcr()
      _waspConnection = New SqlConnection("Data Source=JURA;Initial Catalog=" & WASP & ";User id=" & ConfigurationManager.AppSettings("WASPDBUserName") & ";Password='" & ConfigurationManager.AppSettings("WASPDBPassword").ToString & "';")
    End If
    Return _waspConnection
  End Get
End Property
0 голосов
/ 26 апреля 2010

Когда вы создаете новое соединение, WASP содержит значение, которое вы хотите, чтобы оно было?Это строковый тип данных?Попробуйте добавить .ToString после WASP и посмотрите, поможет ли это.

Интересная проблема.= -)

0 голосов
/ 22 апреля 2010

[текст ссылки] [1] Вы строите свою строку на лету, добавляя значение столбца в строку.Итак, для рассматриваемой строки для столбца «WASPDatabase» был прикреплен к вашей строке.Итак, вы получили то, что имели.С другой стороны, ваш предыдущий запрос «select ... from ... where ...», в котором вы вручную объединяете строку переменной, делает вас ШИРОКИ ОТКРЫТЫМИ для атак SQL-инъекцией.

Хотя этоссылка [1]: как обновить таблицу с использованием параметров oledb? «Пример запроса с использованием параметризации» - это пример запроса C # с параметризованными значениями, аналогичные принципы применимы к большинству всех баз данных SQL.

0 голосов
/ 22 апреля 2010

Возможно, вам захочется выйти из системы, если вы нашли свою базу данных:

For i As Integer = 0 To dt.Rows.Count - 1
            If dt.Rows(i)("WASPDatabase") Is DBNull.Value Then
                WASP = ""
            Else
                WASP = "WaspTrackAsset_" + dt.Rows(i)("WASPDatabase")
                break
            End If

        Next
...