2011-07-01 60 views
0

我有两个SQL查询:OLEDB查询到SQL Server失败

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设置为字符串中的工作,但不是当它被设置为字符串B.

这使我怀疑,有什么不对的条款 WHERE userCompareStr = 'GAPYLE1111'

我不能以这种方式使用alias userCompareStr吗?我找不到任何这种用法的例子,但是当别名用于表名时,我确实发现了类似的用法 - 而且我没有看到任何反对这种用法的东西。

回答

1

你有三个选择。

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)在线查询看到Maziar塔赫里的答案

由于我希望'GAPYLE1111'不是来自用户输入,否则你会暴露自己的SQL注入攻击。改用参数化查询

+0

这是我所有的消息。感谢您的额外指针。我会研究它。 – elbillaf

+0

@TheFallibleFiend没有问题这里是关于这个主题的规范漫画http://xkcd.com/327/ –

+0

它在我看来像OLEDB不喜欢“与”。 我已经简化了SQL,期待它返回任何结果,但至少执行: WITH AS CTE (SELECT(姓+姓名+中间名 + ssn4)作为userCompareStr FROM atable) SELECT userCompareStr FROM CTE WHERE userCompareStr ='GAPYLE1111'; 但它失败了。我不确定,但我认为oledb不能识别所有的sql。我会尝试一些其他的例子。 – elbillaf

1

你不能使用你的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' ; 
0

我离开了一段时间的问题,工作了一些其他东西,并回到它。 我通过从使用oledb切换到“别的东西”解决了主要问题。 我不知道什么新的(对我)方法被称为 - 除了“本机sqlserver?”

要点:

  1. 不能在WHERE子句中使用的字段名称别名。(根据maziar和亚光)

  2. 康拉德的修复#1在OLEDB上工作,但我不喜欢这种方法,因为它是冗长的(而且真正的命令比我在这里提供的按比例缩小的例子复杂得多)并且有很多不同的调用。容易出错并且难以阅读(但在捏合中起作用)。

  3. 要获得WITH或嵌套选择工作,我必须从OLEDB切换到“本机sqlserver”(或任何它所谓的)。 WITH(如康拉德所建议的)是我的首选解决方案 - 读起来更容易。当我从OLEDB切换到本地时,嵌套选择(由Maziar建议)也适用。

  4. 我需要切换到“参数化查询”以避免Conrad注意到的SQL注入攻击。

无论如何,上述建议工作,当我切换到该方法。 而不是使用

Provider=SQLOLEDB 

我用:

providerName="System.Data.SqlClient" 

我现在没有提及OLEDB(如oledbadapter),而是做出SqlDataAdapter的引用。我忽略了upper,ltrim和trim函数(因为事实证明它们不是问题)并且关注oledb一直在窒息的WITH。这是我得到了什么工作:

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 

,但我需要一些时间来试验吧。感谢您的帮助和指示。