我们所有使用关系数据库的人都知道(或正在学习)SQL是不同的。获得期望的结果,并有效地这样做,涉及到一个乏味的过程,其部分特征是学习不熟悉的范例,并发现一些我们最熟悉的编程模式在这里不起作用。常见的反模式是什么?


当前回答

也许这不是一个反模式,但它惹恼了我,当某些数据库的DBA(好吧,我在这里说的是Oracle)用Oracle风格和代码约定编写SQL Server代码,当它运行如此糟糕时抱怨。受够了游标Oracle的人!SQL是基于设置的。

其他回答

使用无意义的表别名:

from employee t1,
department t2,
job t3,
...

使得阅读一个大的SQL语句比它需要的要困难得多

我一直对大多数程序员倾向于在数据访问层混合他们的ui逻辑感到失望:

SELECT
    FirstName + ' ' + LastName as "Full Name",
    case UserRole
        when 2 then "Admin"
        when 1 then "Moderator"
        else "User"
    end as "User's Role",
    case SignedIn
        when 0 then "Logged in"
        else "Logged out"
    end as "User signed in?",
    Convert(varchar(100), LastSignOn, 101) as "Last Sign On",
    DateDiff('d', LastSignOn, getDate()) as "Days since last sign on",
    AddrLine1 + ' ' + AddrLine2 + ' ' + AddrLine3 + ' ' +
        City + ', ' + State + ' ' + Zip as "Address",
    'XXX-XX-' + Substring(
        Convert(varchar(9), SSN), 6, 4) as "Social Security #"
FROM Users

通常,程序员这样做是因为他们想要将数据集直接绑定到一个网格上,而且在服务器端使用SQL Server格式比在客户端使用SQL Server格式更方便。

像上面所示的查询是非常脆弱的,因为它们将数据层与UI层紧密耦合在一起。最重要的是,这种编程风格彻底阻止了存储过程的可重用性。

使用@@IDENTITY代替SCOPE_IDENTITY()

引自以下回答:

@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes. You need to be careful here, since it's across scopes. You could get a value from a trigger, instead of your current statement. SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope. Generally what you want to use. IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope. This lets you specify which table you want the value from, in case the two above aren't quite what you need (very rare). You could use this if you want to get the current IDENTITY value for a table that you have not inserted a record into.

FROM TableA, TableB WHERE语法用于连接而不是FROM TableA内部连接TableB上 假设查询将以某种方式返回,而不放入ORDER BY子句,因为这是在查询工具中测试时显示的方式。

不必深入浅出:不使用准备好的语句。