OLEDB запрос к SQL Server не выполняется - PullRequest
0 голосов
/ 01 июля 2011

У меня есть два запроса SQL:

A.

SELECT (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + 
     upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) AS userCompareStr 
FROM atable ;

и

B.

SELECT (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + 
      upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) AS userCompareStr 
 FROM atable  WHERE userCompareStr='GAPYLE1111' ;

У меня есть следующий код:

    Dim sql As String
    Dim conn As OleDbConnection
    Dim cmd As OleDbDataAdapter
    Dim ds As DataSet
    Dim tbl As DataTable

    conn = " something here "
    cmd = New OleDbDataAdapter(sql, conn)
    ds = New DataSet
    cmd.Fill(ds)
    tbl = New DataTable
    tbl = ds.Tables(0)

Насколько я могу судить, он работает, когда для sql задана строка A, но не для строки B.

Это заставляет меня подозревать, что с предложением что-то не так ГДЕ userCompareStr = 'GAPYLE1111'

Могу ли я не использовать псевдоним userCompareStr таким образом? Я не могу найти никаких примеров такого использования, но я нахожу аналогичное использование, когда псевдоним используется для имени таблицы - и я ничего не вижу против такого рода нас.

Ответы [ 4 ]

1 голос
/ 01 июля 2011

вы не можете использовать псевдоним, который вы установили в предложении select, внутри предложения where.

попробуйте это:

SELECT * FROM
(
SELECT (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) AS userCompareStr FROM atable)
as nested
WHERE userCompareStr='GAPYLE1111' ;
1 голос
/ 01 июля 2011

У вас есть три варианта.

1) повторить то, что вы сделали в списке выбора в

SELECT (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + 
      upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) AS userCompareStr 
FROM atable  

WHERE  (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + 
      upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) ='GAPYLE1111' ;

2) Использовать общее табличное выражение

with CTE AS 
(SELECT (upper(rtrim(ltrim(lastname))) + upper(rtrim(ltrim(firstname))) + 
      upper(rtrim(ltrim(middlename))) + rtrim(ltrim(v)) ) AS userCompareStr 
FROM atable  )
SELECT userCompareStr FROM CTE where userCompareStr = 'GAPYLE1111';

3) Встроенный запрос см. Ответ Мазьяра Тахери

Кроме того, я надеюсь, что «GAPYLE1111» не исходит от пользовательского ввода, иначе вы подвергаете себя атакам SQL-инъекций. Вместо этого используйте параметризованные запросы

1 голос
/ 01 июля 2011

Нет, нельзя использовать столбец с псевдонимами в предложении WHERE.

См. Использование столбца Alias ​​в предложении where в ms-sql 2000

(статья о SQL 2000, но она применяется и сегодня)

0 голосов
/ 07 июля 2011

Я ненадолго отошел от проблемы, занялся чем-то другим и вернулся к ней. Я решил основную проблему, переключившись с использования oledb на «что-то другое». Я не уверен, как называется новый (для меня) метод - кроме, может быть, "native sqlserver?"

Важные моменты:

  1. Невозможно использовать псевдоним имени поля в предложении WHERE. (согласно масиару и мату)

  2. Исправление Конрада № 1 работало на OLEDB, но мне не нравится этот метод, потому что он многословен (а настоящая команда намного сложнее, чем уменьшенный пример, который я привожу здесь), и есть много разные вызовы. Склонен к ошибкам и труден для чтения (но работает в крайнем случае).

  3. Чтобы получить WITH или вложенную работу select, мне пришлось переключиться с OLEDB на «собственный sqlserver» (или как там он называется). WITH (как предложено Конрадом) - мое предпочтительное решение - гораздо легче читать. Вложенный выбор (предложенный Мазиаром) также работает, когда я переключаюсь с OLEDB на нативный.

  4. Мне нужно переключиться на «параметризованные запросы», чтобы избежать атак SQL-инъекций, как отметил Конрад.

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

Provider=SQLOLEDB

Я использовал:

providerName="System.Data.SqlClient"

Теперь я не делаю ссылки на oledb (например, oledbadapter), а вместо этого делаю ссылки на sqlDataAdapter. Я игнорирую верхнюю, итримовую и триммирующую функции (поскольку выясняется, что они не были проблемой) и сосредотачиваюсь на WITH, который был задушен oledb. Вот что я получил на работу:

    Dim conn As New SqlConnection("server=localhost;database=DB;Integrated Security=SSPI;")
    Dim sql As String
    Dim da As SqlDataAdapter

    Dim ds As DataSet = New DataSet()
    Dim tbl As DataTable = New DataTable

    conn = New SqlConnection()
    conn.ConnectionString =    ConfigurationManager.ConnectionStrings("DB").ConnectionString

    Sql = " WITH cte AS "
    sql = sql & "(lastname + firstname + middlename"
    Sql = Sql & "     + v) as userCompareStr FROM atable ) "
    sql = sql & "SELECT userCompareStr   FROM cte WHERE userCompareStr = '" & "GAPYLE1111" & "' ;"

    da = New SqlDataAdapter(sql, conn)
    da.Fill(ds)
    tbl = ds.Tables(0)
    TextBox2.Text = sql

    If tbl.Rows.Count < 1 Then
        TextBox1.Text = "no items"
    Else
        TextBox1.Text = tbl.Rows.Count & " items selected"
    End If


    conn.Dispose()

Также в web.config я добавил:

Я еще не добавил исправления для SQL-инъекций, но я изучаю их и теперь уверен, что это то, что мне нужно сделать. Я нашел некоторую информацию об этом здесь:

http://msdn.microsoft.com/en-us/library/ff648339.aspx

и здесь:

http://weblogs.asp.net/cibrax/archive/2006/09/28/Parameterized-Queries-_2800_Oracle_2C00_-SQLServer_2C00_-OleDb_2900_.aspx

но мне нужно время, чтобы поэкспериментировать с ним. Спасибо за помощь и указатели.

...