Pergunta

Por que alguém iria uso WHERE 1=1 AND <conditions> em uma cláusula SQL (SQL Ou obtido através de cadeias concatenadas, seja definição da visão)

Eu vi em algum lugar que isso seria usado para proteger contra SQL Injection, mas parece muito estranho.

Se houver WHERE 1 = 1 AND injected OR 1=1 injeção teria o mesmo resultado que injected OR 1=1.

Editar mais tarde:? E sobre o uso de uma definição de exibição


Obrigado por suas respostas.

Ainda assim, Eu não entendo por que alguém iria usar esta construção para a definição de uma visão, ou usá-lo dentro de um procedimento armazenado.

Tome este por exemplo:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 AND table.Field=Value
Foi útil?

Solução

Se a lista de condições não é conhecido em tempo de compilação e em vez disso é construída em tempo de execução, você não tem que se preocupar se você tiver um ou mais de uma condição. Você pode gerá-los todos como:

and <condition>

e concatenar-los todos juntos. Com a 1=1 no início, o and inicial tem algo a associar.

Eu nunca vi isso usado para qualquer tipo de proteção injeção, como você diz que não parece que ele iria ajudar muito. I Tem vi sendo utilizado como uma conveniência implementação. O mecanismo de consulta SQL vai acabar ignorando o 1=1 por isso não deve ter nenhum impacto no desempenho.

Outras dicas

Basta adicionar um código de exemplo para a resposta de Greg:

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

Eu já vi isso usado quando o número de condições pode ser variável.

Você pode concatenar condições usando um "E" string. Então, em vez de contar o número de condições que você está passando, você colocar um "onde 1 = 1" no final da sua declaração de estoque SQL e jogue sobre as condições concatenadas.

Basicamente, você economiza ter que fazer um teste para condições e, em seguida, adicionar um "ONDE" string antes deles.

Parece uma forma preguiçosa de sempre saber que a sua cláusula WHERE já está definido e permitir-lhe continuar a acrescentar condições sem ter que verificar se ele é o primeiro.

indirectamente relevantes: 1 quando é usado = 2:

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

Isto irá criar uma nova tabela com o mesmo esquema como tabela antiga. (Muito útil se você quiser carregar alguns dados para compara)

1 = 1 expressão é comumente utilizado em código SQL gerado. Esta expressão pode simplificar o código de geração de SQL reduzindo o número de instruções condicionais.

onde 1 = 0, Isto é feito para verificar se a tabela existe. Não sei porque 1 = 1 é usado.

Na verdade, eu já vi esse tipo de coisa usada em relatórios BIRT. A consulta passada para o tempo de execução BIRT é da forma:

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

e o '? é substituído no tempo de execução por um valor de parâmetro actual seleccionado a partir de uma caixa suspensa. As opções no drop-down são dadas por:

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

para que você obtenha todos os valores possíveis Plus "*". Se o usuário seleciona "*" a partir da caixa drop-down (ou seja, todos os valores de um deve ser selecionado), a consulta tem de ser modificado (por Javascript) antes de ser executado.

Uma vez que o "?" é um parâmetro posicional e deve permanecer lá por outras coisas para trabalhar, o Javascript modifica a consulta a ser:

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

Isso basicamente elimina o efeito da cláusula onde ao mesmo tempo deixando o parâmetro posicional no lugar.

Eu também vi o E caso usado por programadores preguiçosos enquanto criando dinamicamente uma consulta SQL.

Say você tem que criar dinamicamente uma consulta que começa com select * from t e verificações:

  • O nome é Bob; e
  • o salário é> $ 20.000

algumas pessoas adicionar o primeiro com um WHERE e subsequentes aqueles com um e, assim:

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

programadores preguiçosos (e isso não é necessariamente um mau característica) não distinguir entre as condições adicionadas, eles começariam com select * from t where 1=1 e apenas adicionar e cláusulas depois disso.

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

Eu encontrei útil esse padrão quando eu estou testando ou verificar novamente as coisas no banco de dados, para que eu possa comentar muito rapidamente outras condições:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
AND Table.Field=Value
AND Table.IsValid=true

se transforma em:

CREATE VIEW vTest AS
SELECT FROM Table WHERE 1=1 
--AND Table.Field=Value
--AND Table.IsValid=true

Enquanto eu posso ver que 1 = 1 seria útil para SQL gerado, um uso que eu técnica em PHP é criar uma série de cláusulas e depois fazer

implode (" AND ", $clauses);

evitando assim o problema de ter uma esquerda ou à direita E. Obviamente, isso só é útil se você sabe que você está indo para ter pelo menos uma cláusula!

Aqui está um exemplo intimamente relacionados: usando uma instrução SQL MERGE para atualizar o alvo apresentadas utilizando todos os valores da tabela de origem, onde não há nenhum atributo comum sobre o qual se juntar no exemplo

MERGE INTO Circles
   USING 
      (
        SELECT pi
         FROM Constants
      ) AS SourceTable
   ON 1 = 1
WHEN MATCHED THEN 
  UPDATE
     SET circumference = 2 * SourceTable.pi * radius;

Se você veio aqui procurando WHERE 1, nota que WHERE 1 e WHERE 1=1 são idênticos. WHERE 1 é usado raramente porque alguns sistemas de banco de dados rejeitá-la considerando WHERE 1 não sendo realmente boolean.

Isto é útil no caso em que você tem que usar consulta dinâmica em que em que cláusula você tem que adicionar algumas opções de filtro. Como se você incluir as opções 0 para o status está inativo, 1 para ativo. Com base nas opções, há apenas duas opções disponíveis (0 e 1), mas se você quiser exibir todos os registros, é útil para incluir em onde cerca de 1 = 1. Veja abaixo exemplo:

Declare @SearchValue    varchar(8) 
Declare @SQLQuery varchar(max) = '
Select [FirstName]
    ,[LastName]
    ,[MiddleName]
    ,[BirthDate]
,Case
    when [Status] = 0 then ''Inactive''
    when [Status] = 1 then ''Active''
end as [Status]'

Declare @SearchOption nvarchar(100)
If (@SearchValue = 'Active')
Begin
    Set @SearchOption = ' Where a.[Status] = 1'
End

If (@SearchValue = 'Inactive')
Begin
    Set @SearchOption = ' Where a.[Status] = 0'
End

If (@SearchValue = 'All')
Begin
    Set @SearchOption = ' Where 1=1'
End

Set @SQLQuery = @SQLQuery + @SearchOption

Exec(@SQLQuery);

Tendo rever todas as respostas i decidiu realizar alguma experiência como

SELECT
*
FROM MyTable

WHERE 1=1

Então eu verifiquei com outros números

WHERE 2=2
WHERE 10=10
WHERE 99=99

ect Tendo feito todas as verificações, a cidade consulta prazo é o mesmo. mesmo sem a cláusula WHERE. Eu não sou um fã da sintaxe

Usando um predicado como 1=1 é uma dica normal, por vezes utilizado para forçar o plano de acesso para usar ou não usar uma varredura de índice. A razão para isso é usado é quando você estiver usando uma consulta multi-aninhadas se juntou com muitos predicados na cláusula where, onde, por vezes, até mesmo usando todos os índices faz com que o plano de acesso para ler cada mesa - uma varredura completa da tabela. Esta é apenas uma das muitas dicas usados ??por DBAs para enganar um SGBD em usar um caminho mais eficiente. Apenas não jogue um em; você precisa de um dba para analisar a consulta, uma vez que nem sempre funciona.

Eu faço isso geralmente quando eu estou construindo SQL dinâmico para um relatório que tem muitas suspensa valoriza um usuário pode selecionar. Como o usuário pode ou não selecionar os valores de cada suspensa, acabamos ficando um tempo difícil descobrir qual condição foi o primeiro onde cláusula. Então, nós pad-se a consulta com um where 1=1 no final e adicionar todos onde cláusulas depois disso.

Algo como

select column1, column2 from my table where 1=1 {name} {age};

Então, nós podemos construir o onde cláusula como essa e passá-lo como um valor de parâmetro

string name_whereClause= ddlName.SelectedIndex > 0 ? "AND name ='"+ ddlName.SelectedValue+ "'" : "";

Como o onde a seleção cláusula são desconhecidos para nós em tempo de execução, de modo que isso nos ajuda muito na busca de se incluir uma 'AND' or 'WHERE'.

eu me deparei com esta de volta com o ADO e ASP clássico, a resposta que obtive foi:. desempenho se você fizer um straight

Select * from tablename

e passar que no como um comando sql / texto que você vai ter um aumento de desempenho perceptível com o

Where 1=1

acrescentou, era uma diferença visível. algo a ver com os cabeçalhos da tabela sendo devolvido assim que a primeira condição for atendida, ou alguma outra loucura, de qualquer maneira, ele fez acelerar as coisas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top