49

I saw a query run in a log file on an application. and it contained a query like:

SELECT ID FROM CUST_ATTR49 WHERE 1=0

what is the use of such a query that is bound to return nothing?

5
  • 2
    it most likely is a hack to work around some ORM "feature".
    – tereško
    Commented Feb 4, 2012 at 11:46
  • Where did you find such query? Commented Feb 4, 2012 at 11:46
  • Duplicate: stackoverflow.com/questions/517107/…
    – Krumelur
    Commented Feb 4, 2012 at 11:48
  • as far as ORM is concerned, this one does not use any thing like TOPLink or Hibernate. It has its own implementation is what I have heard
    – MozenRath
    Commented Feb 4, 2012 at 11:48
  • 4
    @Krumelur: I wouldn't say this is a duplicate, WHERE 1 = 1 returns all rows from the table and WHERE 1 = 0 returns none, which means they can be used differently as mentioned in the top answer
    – Boris
    Commented Mar 4, 2015 at 16:28

14 Answers 14

81

A query like this can be used to ping the database. The clause:

WHERE 1=0

Ensures that non data is sent back, so no CPU charge, no Network traffic or other resource consumption.

A query like that can test for:

  • server availability
  • CUST_ATTR49 table existence
  • ID column existence
  • Keeping a connection alive
  • Cause a trigger to fire without changing any rows (with the where clause, but not in a select query)
  • manage many OR conditions in dynamic queries (e.g WHERE 1=0 OR <condition>)
2
  • 4
    Another possible use: if you have a trigger on your table for e.g. DELETE you can do DELETE FROM [Table] WHERE 1 = 0 and that will cause the trigger to fire without changing any rows. Useful if for example your trigger updates other tables and you want to ensure everything's up-to-date, etc.
    – Boris
    Commented Mar 4, 2015 at 16:19
  • 3
    @AndreaColleoni you should add the use where we can add 1=0 with a lot of or conditions while making a dynamic query
    – MozenRath
    Commented Mar 12, 2015 at 17:17
25

This may be also used to extract the table schema from a table without extracting any data inside that table. As Andrea Colleoni said those will be the other benefits of using this.

11

A usecase I can think of: you have a filter form where you don't want to have any search results. If you specify some filter, they get added to the where clause.

Or it's usually used if you have to create a sql query by hand. E.g. you don't want to check whether the where clause is empty or not..and you can just add stuff like this:

where := "WHERE 0=1"

if X then where := where + " OR ... "
if Y then where := where + " OR ... "

(if you connect the clauses with OR you need 0=1, if you have AND you have 1=1)

1
  • how exactly? can you provide an example?
    – MozenRath
    Commented Feb 4, 2012 at 11:49
6

As an answer - but also as further clarification to what @AndreaColleoni already mentioned:

manage many OR conditions in dynamic queries (e.g WHERE 1=0 OR <condition>)

Purpose as an on/off switch

I am using this as a switch (on/off) statement for portions of my Query.

If I were to use

WHERE 1=1
  AND (0=? OR first_name = ?) 
  AND (0=? OR last_name = ?)

Then I can use the first bind variable (?) to turn on or off the first_name search criterium. , and the third bind variable (?) to turn on or off the last_name criterium.

I have also added a literal 1=1 just for esthetics so the text of the query aligns nicely.

For just those two criteria, it does not appear that helpful, as one might thing it is just easier to do the same by dynamically building your WHERE condition by either putting only first_name or last_name, or both, or none. So your code will have to dynamically build 4 versions of the same query. Imagine what would happen if you have 10 different criteria to consider, then how many combinations of the same query will you have to manage then?

Compile Time Optimization

I also might add that adding in the 0=? as a bind variable switch will not work very well if all your criteria are indexed. The run time optimizer that will select appropriate indexes and execution plans, might just not see the cost benefit of using the index in those slightly more complex predicates. Hence I usally advice, to inject the 0 / 1 explicitly into your query (string concatenating it in in your sql, or doing some search/replace). Doing so will give the compiler the chance to optimize out redundant statements, and give the Runtime Executer a much simpler query to look at.

(0=1 OR cond = ?) --> (cond = ?)
(0=0 OR cond = ?) --> Always True (ignore predicate)

In the second statement above the compiler knows that it never has to even consider the second part of the condition (cond = ?), and it will simply remove the entire predicate. If it were a bind variable, the compiler could never have accomplished this.

Because you are simply, and forcedly, injecting a 0/1, there is zero chance of SQL injections.

In my SQL's, as one approach, I typically place my sql injection points as ${literal_name}, and I then simply search/replace using a regex any ${...} occurrence with the appropriate literal, before I even let the compiler have a stab at it. This basically leads to a query stored as follows:

WHERE 1=1
  AND (0=${cond1_enabled} OR cond1 = ?)
  AND (0=${cond2_enabled} OR cond2 = ?)

Looks good, easily understood, the compiler handles it well, and the Runtime Cost Based Optimizer understands it better and will have a higher likelihood of selecting the right index.

I take special care in what I inject. Prime way for passing variables is and remains bind variables for all the obvious reasons.

4

This is very good in metadata fetching and makes thing generic. Many DBs have optimizer so they will not actually execute it but its still a valid SQL statement and should execute on all DBs. This will not fetch any result, but you know column names are valid, data types etc. If it does not execute you know something is wrong with DB(not up etc.) So many generic programs execute this dummy statement for testing and fetching metadata.

3

Some systems use scripts and can dynamically set selected records to be hidden from a full list; so a false condition needs to be passed to the SQL. For example, three records out of 500 may be marked as Privacy for medical reasons and should not be visible to everyone. A dynamic query will control the 500 records are visible to those in HR, while 497 are visible to managers. A value would be passed to the SQL clause that is conditionally set, i.e. ' WHERE 1=1 ' or ' WHERE 1=0 ', depending who is logged into the system.

2

quoted from Greg

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

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.

Why would someone use WHERE 1=1 AND <conditions> in a SQL clause?

1
  • 1
    I read that but dint think that OR would be used in case of 1=0 until I got answers for this question
    – MozenRath
    Commented Feb 4, 2012 at 12:00
1

If the user intends to only append records, then the fastest method is open the recordset without returning any existing records.

1

It can be useful when only table metadata is desired in an application. For example, if you are writing a JDBC application and want to get the column display size of columns in the table.

Pasting a code snippet here

String query = "SELECT * from <Table_name> where 1=0";
PreparedStatement stmt = connection.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsMD  = rs.getMetaData();
int columnCount = rsMD.getColumnCount();
for(int i=0;i<columnCount;i++) {
    System.out.println("Column display size is: " + rsMD.getColumnDisplaySize(i+1));
}

Here having a query like "select * from table" can cause performance issues if you are dealing with huge data because it will try to fetch all the records from the table. Instead if you provide a query like "select * from table where 1=0" then it will fetch only table metadata and not the records so it will be efficient.

1

Per user milso in another thread, another purpose for "WHERE 1=0":

CREATE TABLE New_table_name as select * FROM Old_table_name WHERE 1 = 2;

this will create a new table with same schema as old table. (Very handy if you want to load some data for compares)

1
  • Your reference exposes a problem with this approach: if usage isn't centralized or generalized, then we have to search code for all instances for something like "[0-9]+\w+=[0-9]+\w+" (regex) to find all usages.
    – Tenacious
    Commented Jan 28, 2023 at 0:03
1

An example of using a where condition of 1=0 is found in the Northwind 2007 database. On the main page the New Customer Order and New Purchase Order command buttons use embedded macros with the Where Condition set to 1=0. This opens the form with a filter that forces the sub-form to display only records related to the parent form. This can be verified by opening either of those forms from the tree without using the macro. When opened this way all records are displayed by the sub-form.

1

In sql such query can be used when we want to copy only the titles of the columns but not the content.

For example let there be a table worker with columns id and name. Now we want to clone the table structure but not the content of the table itself to a new table called workercopy. Then we use an sql query of

SELECT * INTO workercopy FROM worker WHERE 1=0;
0

In ActiveRecord ORM, part of RubyOnRails:

Post.where(category_id: []).to_sql

# => SELECT * FROM posts WHERE 1=0

This is presumably because the following is invalid (at least in Postgres):

select id FROM bookings WHERE office_id IN ()
-3

It seems like, that someone is trying to hack your database. It looks like someone tried mysql injection. You can read more about it here: Mysql Injection

1
  • First of all, it is called SQL Injection, not mysql injection. Secondly, it is a commonly used practice that by itself does not reveal any malicious intent and is not directly related to SQL injection, although I typically inject the 1 = 0 for query plan performance.
    – YoYo
    Commented Nov 15, 2018 at 12:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.