views:

13243

answers:

12

Why would someone use WHERE 1=1 AND <conditions> in a SQL clause (Either SQL obtained through concatenated strings, either view definition)

I've seen somewhere that this would be used to protect against SQL Injection, but it seems very weird.

If there is injection WHERE 1 = 1 AND injected OR 1=1 would have the same result as injected OR 1=1.

Later edit: What about the usage in a view definition?

+77  A: 

If the list of conditions is not known at compile time and is instead built at run time, you don't have to worry about whether you have one or more than one condition. You can generate them all like:

and <condition>

and concatenate them all together. With the 1=1 at the start, the initial and has something to associate with.

I've never seen this used for any kind of injection protection, as you say it doesn't seem like it would help much. I have seen it used as an implementation convenience. The SQL query engine will end up ignoring the 1=1 so it should have no performance impact.

Greg Hewgill
There have been instances in the past of SQL Server generate poor plans when this technique is used. For that reason, I no longer use it, unless the query is targeted at retrieving schema definition.
Mitch Wheat
Agreed. Vote up for answering the question, but I'd recommend coding the query properly to begin with rather than being lazy.
Ady
Sometimes is not about being lazy, but having a cleaner code.
Eduardo Molteni
dealing with trailing ANDs or COMMAs isn't dirty... nothing is cleaner by having 1=1 all over your SQL.
Yeah, if our DBAs saw that query coming up in their RUNSTATS statistics collections, they'd hunt you down like a duck (and before anyone asks, that's actually a humorous line from the 'Back to the future' movies).
paxdiablo
DBAs? What are they for? :)
Eduardo Molteni
DBA's are there to clean up after programmers who think they know how to use databases effectively.
Adrian Pronk
+5  A: 

Seems like a lazy way to always know that your WHERE clause is already defined and allow you to keep adding conditions without having to check if it is the first one.

duckworth
+4  A: 

1 = 1 expression is commonly used in generated sql code. This expression can simplify sql generating code reducing number of conditional statements.

aku
+10  A: 

I've seen it used when the number of conditions can be variable.

You can concatenate conditions using an " AND " string. Then, instead of counting the number of conditions you're passing in, you place a "WHERE 1=1" at the end of your stock SQL statement and throw on the concatenated conditions.

Basically, it saves you having to do a test for conditions and then add a "WHERE" string before them.

Carl
That's exactly what I do - couldn't have said it better myself.
Eli
A: 

A sanity test.

dove
+27  A: 

Just adding a example code to Greg's answer:

dim sqlstmt as new StringBuilder
sqlstmt.add("SELECT * FROM Products")
sqlstmt.add(" WHERE 1=1") 

''// From now on you don't have to worry if you must 
''// append AND or WHERE because you know the WHERE is there
If ProductCategoryID <> 0 then
  sqlstmt.AppendFormat(" AND ProductCategoryID = {0}", trim(ProductCategoryID))
end if
If MinimunPrice > 0 then
  sqlstmt.AppendFormat(" AND Price >= {0}", trim(MinimunPrice))
end if
Eduardo Molteni
bit hacky, but seems like a valid use.
Mike
+1  A: 

Actually, I've seen this sort of thing used in BIRT reports. The query passed to the BIRT runtime is of the form:

select a,b,c from t where a = ?

and the '?' is replaced at runtime by an actual parameter value selected from a drop-down box. The choices in the drop-down are given by:

select distinct a from t
union all
select '*' from sysibm.sysdummy1

so that you get all possible values plus "*". If the user selects "*" from the drop down box (meaning all values of a should be selected), the query has to be modified (by Javascript) before being run.

Since the "?" is a positional parameter and MUST remain there for other things to work, the Javascript modifies the query to be:

select a,b,c from t where ((a = ?) or (1==1))

That basically removes the effect of the where clause while still leaving the positional parameter in place.

I've also seen the AND case used by lazy coders whilst dynamically creating an SQL query.

Say you have to dynamically create a query that starts with select * from t and checks:

  • the name is Bob; and
  • the salary is > $20,000

some people would add the first with a WHERE and subsequent ones with an AND thus:

select * from t where name = 'Bob' and salary > 20000

Lazy programmers wouldn't distinguish between the added conditions, they'd start with select * from t where 1=1 and just add AND clauses after that.

select * from t where 1=1 and name = 'Bob' and salary > 20000
paxdiablo
+1  A: 

Thank you for your answers.

Still, I don't understand why would someone use this construction for defining a view, or use it inside a stored procedure.

Take this for example:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
Bogdan Maxim
In that case, someone who didn't know better saw it somewhere and thought they needed it, or code that was originally in the application was re-factored to belong to the database without really paying attention to what it was doing.
Joel Coehoorn
+1 to that. My immediate thought was "Cargo Cult"
Mike Woodhouse
Or, depending on location, that could be the output of the script, with only one necessary clause.
Eli
+1  A: 

I first came across this back with ADO and classic asp, the answer i got was: performance. if you do a straight

Select * from tablename

and pass that in as an sql command/text you will get a noticeable performance increase with the

Where 1=1

added, it was a visible difference. something to do with table headers being returned as soon as the first condition is met, or some other craziness, anyway, it did speed things up.

jackberry
That sounds completely idiotic to me, yet entirely believable...
Ant P.
A: 

where 1=0, This is done to check if the table exists. Don't know why 1=1 is used.

+1  A: 

While I can see that 1=1 would be useful for generated SQL, a technique I use in PHP is to create an array of clauses and then do

implode (" AND ", $clauses);

thus avoiding the problem of having a leading or trailing AND. Obviously this is only useful if you know that you are going to have at least one clause!

A: 

i think it's a silly form to program the sql, in fact if you can avoid it, then do it, is better to avoir unncesary instructions in sql.

Carlos Acosta