Por que alguém use onde 1 = 1 e em uma cláusula SQL?
-
04-07-2019 - |
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
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;
quadros singelosPor que alguém use onde 1 = 1 AND
<proper conditions>
Por exemplo (estou usando C # como um exemplo aqui), considere a análise condicional dos seguintes predicados em um string builder
consulta SQL:
var sqlQuery = "SELECT * FROM FOOS WHERE 1 = 1"
if (shouldFilterForBars)
{
sqlQuery = sqlQuery + " AND Bars > 3";
}
if (shouldFilterForBaz)
{
sqlQuery = sqlQuery + " AND Baz < 12";
}
O "benefício" de meios WHERE 1 = 1
que nenhum código especial é necessário:
- Para E - seja zero, um ou ambos os predicados (Bares e Baz de) deve ser aplicada, o que determinaria se o primeiro
AND
é necessária. Uma vez que já têm pelo menos um predicado com o1 = 1
, isso significaAND
é sempre OK. - Para não predicados em tudo - no caso em que há zero predicados, então o
WHERE
deve ser descartado. Mas, novamente, que pode ser preguiçoso, porque estamos de novo garantia de pelo menos um predicado.
Esta é obviamente uma má idéia e gostaria de recomendar utilizando um quadro de acesso de dados estabelecidas ou ORM para analisar predicados opcionais e condicionais desta forma.
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.