最糟糕的SQL

时间:2008-12-31 00:33:51

标签: sql database

您见过的最糟糕的SQL查询是什么?是什么让它变坏了?

21 个答案:

答案 0 :(得分:35)

DELETE FROM table

在我输入并执行它之后看到,我忘记了WHERE子句。现在我总是首先运行SELECT语句,并在我确信正确的行会受到影响后将SELECT更改为DELETE。

答案 1 :(得分:25)

经典xkcd当然:

WHERE name = ROBERT'); DROP TABLE students;--

答案 2 :(得分:13)

每次最错误的 USE SQL查询:

一个SELECT查询,它计算对应于某个条件的行数,在for循环的停止条件中调用。
像这样:

for(int i = 0; i < query("SELECT COUNT .... WHERE ..."); i++)
{

}

不,查询结果不会每次迭代都改变。是的我意识到服务器将缓存结果。

答案 3 :(得分:9)

客户在varchar字段(经典ASP应用程序)中存储了包含3个值的逗号分隔列表,因此它们的存储过程看起来像这样:

SELECT *
FROM
    SomeTable
WHERE
    Field LIKE @Param + ',%'
    OR
    Field LIKE '%,' + @Param + ',%'
    OR
    Field LIKE '%,' + @Param

显然为什么它太可怕了:))

答案 4 :(得分:9)

使用Bubble Sort对结果集进行排序的PL / SQL(Oracle)存储过程。当我和DBA被要求弄清楚一个严重的性能问题时,就发现了它。开发人员,甲骨文“专家”已经为此工作了一个多星期。他直言不讳地解释说,他在计算机科学课上学到了泡泡排序。该算法通常用于说明性能不佳。

用ORDER BY子句替换整个混乱。性能提高了几个数量级。

答案 5 :(得分:6)

select * from users where clue > 0;
0 results found.

答案 6 :(得分:6)

我自己的,这里发布的时间很长 - 现在关闭3500行

我必须真正与一个绝对可怕的架构分担责任。最开始的一个简单的练习是使用一些工会转动非规范化数据,这变成了一个笨拙的噩梦。它非常需要维修。

亚军是这样的:

select 
case datepart(mm,getdate())
when 1 then 'Jan'
when 2 then 'Feb'
when 3 then 'March'
when 4 then 'Apr'
when 5 then 'May'
when 6 then 'Jun'
when 7 then 'July'
when 8 then 'Aug'
when 9 then 'Sept'
when 10 then 'Otc'
when 11 then 'Nov'
when 11 then 'Dec'
end

该帖子中没有拼写错误 - 这就是它的编写方式。谢谢,咨询美元!

我当然用Select left重构(datename(mm,getdate()),3)

答案 7 :(得分:4)

当我第一次获得当前工作时,我的第一个项目是创建一个应用程序,在我们的计算机实验室中汇总我们的许可证使用数据。他坚持认为他不希望后端数据库正常化,因为连接“太贵了”。这是我的第一周,我无法辩论。

现在,为了从数据库中提取任何有用的数据,必须在每个需要提取摘要的查询中“撤消”非规范化,以删除每行中的重复数据。当然,这些是实际使用的唯一查询。如果数据被规范化,您会看到很多嵌套选择,如:

select location, sum(login_time) as total_login_time
from
    (select location, session_id, max(login_time) as login_time
     from sessions
     where location in ('lab1','lab2') 
           and session_start >= @start_date 
           and session_end <= @end_date
     group by location, session_id) tbl
group by location

尽管如此,查询本身并不是特别难看 - 尽管有些是 - 但每次都必须跳过箍来解除不必要的非规范化伤害。

现在老板走了,但我没有时间重写它......

答案 8 :(得分:4)

comp.databases.informix新闻组的帖子中 - 真正有用的Informix表格(我不建议使用):

CREATE TABLE VIEW
(
    DECIMAL     CHAR(30),
    NOT         INTEGER NOT NULL,
    SERIAL      DATE NOT NULL,
    NULL        CHAR(1) NOT NULL,
    INTEGER     DECIMAL(13,6) NOT NULL
);

如果您知道SERIAL是Informix数据库中的一种类型,那么它(略微有用) - 基本上是串行生成自动分配数字的类型之一。

答案 9 :(得分:3)

SUBSTRING(
(SUBSTRING(LastName, 0, CHARINDEX(' ', LastName)) + ', ' + FirstName),
0,
CHARINDEX(' ', (SUBSTRING(LastName, 0, CHARINDEX(' ', LastName)) + ', ' + 
FirstName), LEN(LastName) + 3)
)

他们显然不熟悉RTRIM;

RTRIM(LastName) + ', ' + RTRIM(FirstName)

答案 10 :(得分:2)

大声朗读。

select [select],*,star as [as] from [from],[order] order by [by] 

答案 11 :(得分:2)

从*

中选择*

真的很糟糕。

答案 12 :(得分:2)

这可能不是最糟糕的,但我经常看到这一点(Misuse of the group by clause):

SELECT
  C.CustomerID, C.CustomerName, C.CustomerType, C.Address1, C.City,   
  C.State, SUM(S.Sales) as TotalSales
FROM
  Customers C
INNER JOIN Sales S
  ON C.CustomerID = S.CustomerID
GROUP BY
  C.CustomerID, C.CustomerName, C.CustomerType, C.Address1, C.City, C.State

代替:

SELECT
  C.CustomerID, C.CustomerName,
  C.CustomerType, C.Address1, C.City,
  C.State, S.TotalSales
FROM
  Customers C
INNER JOIN
  (SELECT CustomerID, SUM(Sales) as TotalSales FROM Sales GROUP BY CustomerID) S
ON
  C.CustomerID = S.CustomerID

答案 13 :(得分:2)

我认为这是最糟糕的(尤其是痛苦和无效的回滚):

DROP DATABASE;
ROLLBACK;

答案 14 :(得分:1)

在Access数据库中,存在如下查询:

SELECT *
FROM Bad_2 INNER JOIN Bad_1 ON Bad_2.Bad_1_id = Bad_1.ID;

并且两个表都有一个具有相同名称的字段。当Access第二次遇到字段名称时,它会为它组成一个新名称。前一个人在代码中使用了生成的字段名称。

答案 15 :(得分:1)

在我的时间里看到许多可怜的SQL。 浮现在脑海中的是

形式

从文件加载数据,循环遍历该文件,为文件中的每一行访问db。

对于10行左右的测试系统似乎没问题,100K-1百万=即使对于初级也是讨厌的 密钥查找。

BTW,解决方案是将数据加载到数据库中并进行集合思考。

- 选择你最喜欢的郎。 perl,python ......

将文件加载到数据结构(例如数组)

for (1 .. n) loop
myid := array[n];
select * from table where id = myid;
if the row exists update table set ... where id = myid;
end loop;

答案 16 :(得分:1)

SELECT * FROM some_table;

使代码如此糟糕的原因是代码依赖于根据时间戳获得结果。在我被要求修复它之前,这显然已经工作了一段时间。

答案 17 :(得分:1)

最近,我看到了一个(超过)4000行TSQL存储过程,它是一组用于匹配地址部分的IF语句。它可以减少到不到50行!

我正在为将来的DailyWTF保存代码!

答案 18 :(得分:0)

DELETE FROM some_table WHERE some_thing IN(SELECT some_column_from_wrong_table FROM correct_table WHERE some_id = something)。

some_column_from_wrong_table有一个列甚至不在表中,但它在另一个表中。 问题是correct_table被命名为'Event',并以某种方式返回所有行而不是NO行(或者更重要的是,错误!)。

两个经验教训:在任何情况下都不要在任何形式的系统名称之后命名一个表。第二件事是先运行select语句,然后再更改为删除。

顺便说一下,这是SqlServer 2005。我仍然生气,它没有抛出错误。

答案 19 :(得分:0)

我喜欢dailywtf上的那个reposted recently,它附带的故事也很精彩。

答案 20 :(得分:-1)

SELECT name FROM categories WHERE id IN (".implode(",",corrected_cats($ad->id)).") ORDER BY name ASC

是的,你正在读正确的...字段中的逗号分隔字段。