처음에 1 = 1을 사용하는 것보다 SQL WHERE 절을 동적으로 빌드하는 더 좋은 방법이 있습니까?


110

좀 짓고 있어요 SQL의 C #에서 쿼리를. 코드에 변수로 저장된 일부 조건에 따라 달라집니다.

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) 
    Query += "AND Col1=0 ";
if (condition2) 
    Query += "AND Col2=1 ";
if (condition3) 
    Query += "AND Col3=2 ";

작동하지만 1 = 1 테스트는 우아하게 보이지 않습니다. 사용하지 않았다면 쿼리에 "where"키워드가 이미 추가되었는지 여부를 매번 기억하고 확인해야했습니다.

더 좋은 해결책이 있습니까?


118
나도 이런 식으로 할 것,하지만 난 사용합니다 - 정직합니다 42 = 42;-)
FERO

5
저는 실제로 항상 이와 같은 쿼리를 작성합니다. 그것은 쉽게 조건 주석 할 수 있습니다
Deruijter

4
@catfood 인턴으로 일한 첫 번째 프로젝트는 Sybase 서버에 대한 성능 쿼리를 분석하는 데 도움이되는 도구를 작성하는 것이 었습니다. 흥미로운 발견은 Select 42우리가받은 수십만 개의 쿼리였습니다. (원인을 추적하려고했던 좋지)
Mr.Mindor

24
If I didn't use it, I would have to remember and check every time if "where" keyword was already added or not to the query-그래서 1 = 1. 어쨌든 데이터베이스 엔진은이를 최적화하기 때문에보기 흉할 수 있지만 문제를 해결하는 가장 쉬운 방법입니다.
Robert Harvey

4
주어진 답변이 매우 좋지만 원본 코드가 가장 읽기 쉽다고 생각합니다.
Uooo

답변:


157

목록에 조건을 저장합니다.

List<string> conditions = new List<string>();

if (condition1) conditions.Add("Col1=0");
//...
if (conditions.Any())
    Query += " WHERE " + string.Join(" AND ", conditions.ToArray());

24
좋은 솔루션이지만 ToArray().NET 4에는 IEnumerable<string>.
fero 2013-06-26

101
저는 이것이 제공하는 모든 SQL 인젝션 기회에 대해 기쁩니다.
asteri

12
@Jeff where 절의 값을 하드 코딩하지 않으면 SqlParameters로 두 번째 목록을 가질 수도 있습니다. 조건 목록과 동시에 해당 목록을 채우고 끝에 AddRange (parameters.ToArray ()) 를 호출 하면됩니다.
Scott Chamberlain

5
@ScottChamberlain 예, 입력 문자열을 목록에 넣기 전에 간단히 이스케이프 할 수도 있습니다. 나는 대부분 우스꽝스러운 유머를 사용하여 가능한 공격에 대해 경고했습니다.
asteri

4
@Jeff 조건에 사용자 입력이 포함 된 경우에만 SQL 주입에 취약합니다 (원래 예제에는 포함되지 않음)
D Stanley

85

한 가지 해결책은 단순히 문자열을 추가하여 수동으로 쿼리를 작성하지 않는 것입니다. Entity Framework 와 같은 ORM을 사용할 수 있으며 LINQ to Entities에서는 언어 및 프레임 워크가 제공하는 기능을 사용할 수 있습니다.

using (var dbContext = new MyDbContext())
{
    IQueryable<Table1Item> query = dbContext.Table1;

    if (condition1)
    {
        query = query.Where(c => c.Col1 == 0);
    }
    if (condition2)
    {
        query = query.Where(c => c.Col2 == 1);
    }
    if (condition3)
    {
        query = query.Where(c => c.Col3 == 2);
    }   

    PrintResults(query);
}

@vaheeds 그 질문을 이해하지 못합니다. 둘 다 다른 ORM입니다.
CodeCaster

죄송합니다. dapper의 성능을 다른 ORM과 비교하기 위해 검색 중이 었는데 Google에서 여기에 도착했기 때문에 생성 된 PrintResults(query)쿼리가 dapper에서 쿼리로 사용될 것이라고 생각했습니다 !!
vaheeds jul.

@vaheeds 괜찮습니다.하지만 대답을 이해하지 못한다고해서 반대표를받을 수는 없습니다. 그것이 당신이라면 우연히 당신의 의견과 동시에 일어난 일입니다.
CodeCaster

당신의 권리는 오해였습니다. 복잡한 쿼리에서 linq에서 엔티티에 대한 성능이 저하됩니다. 나는 다른 답변에 의해 반대표를 보상했습니다;)
vaheeds

즉, 질문에 대한 답변하지 않습니다
HGMamaci

17

이 간단한 경우에는 약간의 과잉이 있지만 과거에 이와 유사한 코드를 사용했습니다.

함수 만들기

string AddCondition(string clause, string appender, string condition)
{
    if (clause.Length <= 0)
    {
        return String.Format("WHERE {0}",condition);
    }
    return string.Format("{0} {1} {2}", clause, appender, condition);
}

이렇게 사용하세요

string query = "SELECT * FROM Table1 {0}";
string whereClause = string.Empty;

if (condition 1)
    whereClause = AddCondition(whereClause, "AND", "Col=1");

if (condition 2)
    whereClause = AddCondition(whereClause, "AND", "Col2=2");

string finalQuery = String.Format(query, whereClause);

이렇게하면 조건이 발견되지 않으면 쿼리에서 where 문을로드하지 않아도되며 SQL 문을 구문 분석 할 때 정크 where 절을 처리하는 데 마이크로 초를 절약 할 수 있습니다.


나는 이것이 어떻게 더 우아하게 만드는지 보지 못합니다. 여기서 무슨 일이 일어나고 있는지 분명하지 않습니다. 나는 그 유틸리티 기능의 사용을 볼 수 있지만 더 우아하지는 않습니다.
usr

마이크로 초의 중요성에 대해 우리를 계몽 당신에게 한 표를 준
user1451111

15

우아하지 않을 수도 있지만 작동하고 문제를 해결하는 또 다른 솔루션이 있습니다.

String query = "SELECT * FROM Table1";
List<string> conditions = new List<string>();
// ... fill the conditions
string joiner = " WHERE ";
foreach (string condition in conditions) {
  query += joiner + condition;
  joiner = " AND "
}

에 대한:

  • 빈 조건 목록, 결과는 단순히 SELECT * FROM Table1 ,
  • 하나의 조건이 될 것입니다 SELECT * FROM Table1 WHERE cond1
  • 다음의 각 조건은 추가로 AND condN

6
그 잎은 매달려 WHERE아무런 조건이없는 경우; 1 = 1은이를 피하기 위해 특별히 존재합니다.
Gaius

그래서로 전환 String query = "SELECT * FROM Table1";하고 string jointer = " WHERE ";?
Brendan Long

이어서 @BrendanLong WHERE된다 AND의 조건들 사이에 배치 될?
PenguinCoder 2013-06-26

@PenguinCoder 댓글에 전체 코드를 표시하는 것은 어렵습니다. string joiner줄을로 바꾸고 줄을 string joiner = " WHERE ";그대로 두십시오 joiner = " AND ";.
Brendan Long

@Gaius 나는 coditions가 비어 있지 않다고 생각했지만 조이너에 WHERE를 넣으면 트릭을 수행해야합니다. 발언에 감사드립니다!
Dariusz

11

다음과 같이하십시오.

using (var command = connection.CreateCommand())
{
    command.CommandText = "SELECT * FROM Table1";

    var conditions = "";
    if (condition1)
    {    
        conditions += "Col1=@val1 AND ";
        command.AddParameter("val1", 1);
    }
    if (condition2)
    {    
        conditions += "Col2=@val2 AND ";
        command.AddParameter("val2", 1);
    }
    if (condition3)
    {    
        conditions += "Col3=@val3 AND ";
        command.AddParameter("val3", 1);
    }
    if (conditions != "")
        command.CommandText += " WHERE " + conditions.Remove(conditions.Length - 5);
}

그것의 SQL 주입 안전이럴 , 그것은 꽤 깨끗. 는 Remove()단순히 마지막을 제거AND ;

조건이 설정되지 않았거나 하나가 설정되었거나 여러 개가 설정된 경우 모두 작동합니다.


1
확실하지 않지만 (C #을 사용하지 마십시오) , 초기화 할 때 conditions != null항상 true그렇습니다 ""(C # 제외 "" == null). conditions비어 있지 않다면 아마도 수표 여야합니다 … ;-)
siegi

9

뒤에 두 줄만 추가하면됩니다.

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";
Query.Replace("1=1 AND ", "");
Query.Replace(" WHERE 1=1 ", "");

SELECT * FROM Table1 WHERE 1=1 AND Col1=0 AND Col2=1 AND Col3=2 

될 것이다

SELECT * FROM Table1 WHERE Col1=0 AND Col2=1 AND Col3=2 

동안

SELECT * FROM Table1 WHERE 1=1 

될 것이다

SELECT * FROM Table1

====================================

이 솔루션의 결함을 지적 해 주셔서 감사합니다.

"어떤 이유에서든 조건 중 하나에"1 = 1 AND "또는"WHERE 1 = 1 "이라는 텍스트가 포함 된 경우 쿼리가 중단 될 수 있습니다. 조건에 하위 쿼리가 포함되어 있는지 확인하려는 경우 일 수 있습니다. 예를 들어 열에이 텍스트가 포함되어 있습니다.이 문제는 귀하의 경우에는 문제가되지 않지만 명심해야합니다. "

이 문제를 없애기 위해 "main" WHERE 1 = 1 과 하위 쿼리의 항목 을 구분해야합니다 . 간단합니다.

간단하게 만드는 "기본" WHERE 특별 : 나는 "$"기호를 추가 할

string Query="SELECT * FROM Table1 WHERE$ 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";

그런 다음 두 줄을 추가합니다.

Query.Replace("WHERE$ 1=1 AND ", "WHERE ");
Query.Replace(" WHERE$ 1=1 ", "");

1
어떤 이유로 든 조건 중 하나에 "1=1 AND "또는 텍스트가 포함 된 경우 쿼리가 중단 될 수 있습니다 " WHERE 1=1 ". 예를 들어 조건에 하위 쿼리가 포함되어 있거나 일부 열에이 텍스트가 포함되어 있는지 확인하려는 경우 일 수 있습니다. 어쩌면 ...이 경우에는 문제가되지 않습니다하지만 당신은 마음에 보관한다
siegi은

8

이것을 사용하십시오 :

string Query="SELECT * FROM Table1 WHERE ";
string QuerySub;
if (condition1) QuerySub+="AND Col1=0 ";
if (condition2) QuerySub+="AND Col2=1 ";
if (condition3) QuerySub+="AND Col3=2 ";

if (QuerySub.StartsWith("AND"))
    QuerySub = QuerySub.TrimStart("AND".ToCharArray());

Query = Query + QuerySub;

if (Query.EndsWith("WHERE "))
    Query = Query.TrimEnd("WHERE ".ToCharArray());

이 대답은 효과가있을 것이고, 실제로 잘못된 것은 없지만 원래 질문보다 깨끗하고 간단 하다고 생각하지 않습니다 . QuerySub내 생각에 문자열 검색 은 where 1=1해킹을 사용하는 것보다 낫거나 나쁘지 않다 . 그러나 그것은 사려 깊은 공헌입니다.
catfood

3
오류가있었습니다. 수정했습니다. 조건이 존재하지 않으면 내 질문이 폭파되었을 것입니다. -P 그래도 Ahmed 나 CodeCaster가 나에게 최고의 솔루션이라고 말해야합니다. 나는 너희들을위한 대안을 제시했다!
Anshuman 2013-06-26

이것은 일반적으로 여전히 잘못되었습니다. 그것이 있다고 가정하십시오 ... FROM SOMETABLE WHERE ; 그러면 TrimEnd실제로 이것을 ... FROM SOMETABL. 이것이 실제로 StringBuilder(이 정도의 문자열 조작 이상을 가지고 있다면 있어야 함) Query.Length -= "WHERE ".Length;.
Mark Hurd

마크, 작동합니다. 나는 많은 프로젝트에서 이것을 시도했습니다. 그것을 시도하고 당신은 그것을 찾을 것입니다!
Anshuman 2013-06-26

8
내가 정확히 계산하면 추한 지옥으로 :) 플러스는 7 문자열을 만들 수 있습니다
표트르 페락

5

기존 쿼리 빌더를 사용하지 않는 이유는 무엇입니까? Sql Kata 와 같은 것 .

복잡한 where 조건, 조인 및 하위 쿼리를 지원합니다.

var query = new Query("Users").Where("Score", ">", 100).OrderByDesc("Score").Limit(100);

if(onlyActive)
{
   query.Where("Status", "active")
}

// or you can use the when statement

query.When(onlyActive, q => q.Where("Status", "active"))

Sql Server, MySql 및 PostgreSql에서 작동합니다.


4

내가 생각할 수있는 질문에 대한 가장 빠른 리터럴 솔루션은 다음과 같습니다.

string Query="SELECT * FROM Table1";
string Conditions = "";

if (condition1) Conditions+="AND Col1=0 ";
if (condition2) Conditions+="AND Col2=1 ";
if (condition3) Conditions+="AND Col3=2 ";

if (Conditions.Length > 0) 
  Query+=" WHERE " + Conditions.Substring(3);

우아하게 보이지는 않지만 ORM 사용에 대한 CodeCaster의 권장 사항을 참조합니다. 그러나 이것이 여기서 무엇을하고 있는지 생각해 보면 4 문자의 메모리를 '낭비'하는 것에 대해 정말 걱정할 필요가 없으며 컴퓨터가 포인터를 4 자리로 이동하는 것이 정말 빠릅니다.

ORM 사용법을 배울 시간이 있다면 정말 도움이 될 것입니다. 그러나 이와 관련하여 추가 조건이 SQL db에 도달하지 않도록 유지하려는 경우이 작업이 수행됩니다.


4

이것이 SQL Server 인 경우이 코드를 훨씬 더 깔끔하게 만들 수 있습니다.

이것은 또한 알려진 수의 매개 변수를 가정합니다. 가능성에 대해 생각할 때 잘못된 가정 일 수 있습니다.

C #에서는 다음을 사용합니다.

using (SqlConnection conn = new SqlConnection("connection string"))
{
    conn.Open();
    SqlCommand command = new SqlCommand()
    {
        CommandText = "dbo.sample_proc",
        Connection = conn,
        CommandType = CommandType.StoredProcedure
    };

    if (condition1)
        command.Parameters.Add(new SqlParameter("Condition1", condition1Value));
    if (condition2)
        command.Parameters.Add(new SqlParameter("Condition2", condition2Value));
    if (condition3)
        command.Parameters.Add(new SqlParameter("Condition3", condition3Value));

    IDataReader reader = command.ExecuteReader();

    while(reader.Read())
    {
    }

    conn.Close();
}

그리고 SQL 측에서 :

CREATE PROCEDURE dbo.sample_proc
(
    --using varchar(50) generically
    -- "= NULL" makes them all optional parameters
    @Condition1 varchar(50) = NULL
    @Condition2 varchar(50) = NULL
    @Condition3 varchar(50) = NULL
)
AS
BEGIN
    /*
    check that the value of the parameter 
    matches the related column or that the 
    parameter value was not specified.  This
    works as long as you are not querying for 
    a specific column to be null.*/
    SELECT *
    FROM SampleTable
    WHERE (Col1 = @Condition1 OR @Condition1 IS NULL)
    AND   (Col2 = @Condition2 OR @Condition2 IS NULL)
    AND   (Col3 = @Condition3 OR @Condition3 IS NULL)
    OPTION (RECOMPILE)
    --OPTION(RECOMPILE) forces the query plan to remain effectively uncached
END

표현식 내부에 열을 숨기면 인덱스 사용을 방지 할 수 있으며이 기술은 여기에서 권장하지 않습니다 .
bbsimonbb

흥미로운 발견입니다. 그 정보에 감사드립니다. 업데이트 예정
mckeejm 2016-06-03

3

조건에 따라 쿼리에서 부울 논리를 사용할 수 있습니다. 이 같은 :

string Query="SELECT * FROM Table1  " +
             "WHERE (condition1 = @test1 AND Col1=0) "+
             "AND (condition2 = @test2 AND Col2=1) "+
             "AND (condition3 = @test3 AND Col3=2) ";

3

나는 stringbuilder의 유창한 인터페이스를 좋아하므로 ExtensionMethods를 만들었습니다.

var query = new StringBuilder()
    .AppendLine("SELECT * FROM products")
    .AppendWhereIf(!String.IsNullOrEmpty(name), "name LIKE @name")
    .AppendWhereIf(category.HasValue, "category = @category")
    .AppendWhere("Deleted = @deleted")
    .ToString();

var p_name = GetParameter("@name", name);
var p_category = GetParameter("@category", category);
var p_deleted = GetParameter("@deleted", false);
var result = ExecuteDataTable(query, p_name, p_category, p_deleted);


// in a seperate static class for extensionmethods
public StringBuilder AppendLineIf(this StringBuilder sb, bool condition, string value)
{
    if(condition)
        sb.AppendLine(value);
    return sb;
}

public StringBuilder AppendWhereIf(this StringBuilder sb, bool condition, string value)
{
    if (condition)
        sb.AppendLineIf(condition, sb.HasWhere() ? " AND " : " WHERE " + value);
    return sb;
}

public StringBuilder AppendWhere(this StringBuilder sb, string value)
{
    sb.AppendWhereIf(true, value);
    return sb;
}

public bool HasWhere(this StringBuilder sb)
{
    var seperator = new string [] { Environment.NewLine };
    var lines = sb.ToString().Split(seperator, StringSplitOptions.None);
    return lines.Count > 0 && lines[lines.Count - 1].Contains("where", StringComparison.InvariantCultureIgnoreCase);
}

// http://stackoverflow.com/a/4217362/98491
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    return source.IndexOf(toCheck, comp) >= 0;
}

2

IMHO, 귀하의 접근 방식이 잘못되었다고 생각합니다.

문자열을 연결하여 데이터베이스를 쿼리하는 것은 결코 좋은 생각이 아닙니다 ( SQL 주입의 위험이 있으며 다른 곳에서 변경하면 코드가 쉽게 손상 될 수 있습니다).

당신은 사용할 수 있습니다 ORM (내가 사용하는 자 NHibernate를 ) 또는 적어도 사용에를SqlCommand.Parameters

문자열 연결을 절대적으로 사용하려면 다음을 사용합니다 StringBuilder(문자열 연결에 적합한 개체입니다).

var query = new StringBuilder("SELECT * FROM Table1 WHERE");
int qLength = query.Length;//if you don't want to count :D
if (Condition1) query.Append(" Col1=0 AND");
if (Condition2) query.Append(" Col2=0 AND");
....
//if no condition remove WHERE or AND from query
query.Length -= query.Length == qLength ? 6 : 4;

마지막으로 생각했듯이 Where 1=1정말 못 생겼지 만 SQL Server 는 어쨌든 최적화 할 것입니다.


SELECT * FROM Table1 WHERE AND Col1=0정확하지 않은 것 같습니다 WHERE 1=1.
Mormegil

2

Dapper SqlBuilder 는 꽤 좋은 옵션입니다. StackOverflow의 프로덕션에서도 사용됩니다.

이에 대한 Sam의 블로그 항목 읽기 .

내가 아는 한 Nuget 패키지의 일부가 아니므로 코드를 프로젝트에 붙여 넣거나 Dapper 소스를 다운로드하고 SqlBuilder 프로젝트를 빌드해야합니다. 어느 쪽이든 DynamicParameters클래스에 대해 Dapper를 참조해야합니다 .


1
Dapper의 SqlBuilder가 해당 패키지에 포함되어 있다고 생각하지 않습니다.
Ronnie Overby 2014

1

저장 프로 시저 내에서 동적 SQL을 구축하는 동안 Oracle에서 항상 사용되는 것을 확인했습니다 . 쿼리에서 데이터 문제를 탐색하는 동안뿐만 아니라 다른 데이터 필터간에 빠르게 전환 할 수 있도록 사용합니다. 조건을 주석 처리하거나 쉽게 다시 추가 할 수 있습니다.

코드를 검토하는 사람이 이해할 수있을 정도로 매우 일반적이고 쉽습니다.


1
public static class Ext
{
    public static string addCondition(this string str, bool condition, string statement)
    {
        if (!condition)
            return str;

        return str + (!str.Contains(" WHERE ") ? " WHERE " : " ") + statement;
    }

    public static string cleanCondition(this string str)
    {
        if (!str.Contains(" WHERE "))
            return str;

        return str.Replace(" WHERE AND ", " WHERE ").Replace(" WHERE OR ", " WHERE ");
    }
}

확장 방법으로 실현.

    static void Main(string[] args)
    {
        string Query = "SELECT * FROM Table1";

        Query = Query.addCondition(true == false, "AND Column1 = 5")
            .addCondition(18 > 17, "AND Column2 = 7")
            .addCondition(42 == 1, "OR Column3 IN (5, 7, 9)")
            .addCondition(5 % 1 > 1 - 4, "AND Column4 = 67")
            .addCondition(Object.Equals(5, 5), "OR Column5 >= 0")
            .cleanCondition();

        Console.WriteLine(Query);
    }

곡물에 대항해!
Ronnie Overby

실례합니다? 무슨 뜻이야?
Maxim Zhukov 2013

0

string함수를 사용하면 다음과 같이 할 수도 있습니다.

string Query = "select * from Table1";

if (condition1) WhereClause += " Col1 = @param1 AND "; // <---- put conditional operator at the end
if (condition2) WhereClause += " Col1 = @param2 OR ";

WhereClause = WhereClause.Trim();

if (!string.IsNullOrEmpty(WhereClause))
    Query = Query + " WHERE " + WhereClause.Remove(WhereClause.LastIndexOf(" "));
// else
// no condition meets the criteria leave the QUERY without a WHERE clause  

나는 개인적으로 조건부 요소의 위치를 ​​예측하기 쉽기 때문에 마지막에 제거하기가 쉽다고 느낍니다.


0

나는 아마도 좀 더 읽기 쉬운 해결책을 생각했습니다.

string query = String.Format("SELECT * FROM Table1 WHERE "
                             + "Col1 = {0} AND "
                             + "Col2 = {1} AND "
                             + "Col3 = {2}",
                            (!condition1 ? "Col1" : "0"),
                            (!condition2 ? "Col2" : "1"),
                            (!condition3 ? "Col3" : "2"));

SQL 인터프리터가 Col1 = Col1조건 ( condition1거짓 일 때 인쇄 됨)을 최적화할지 여부는 확실하지 않습니다 .


0

다음은 더 우아한 방법입니다.

    private string BuildQuery()
    {
        string MethodResult = "";
        try
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("SELECT * FROM Table1");

            List<string> Clauses = new List<string>();

            Clauses.Add("Col1 = 0");
            Clauses.Add("Col2 = 1");
            Clauses.Add("Col3 = 2");

            bool FirstPass = true;

            if(Clauses != null && Clauses.Count > 0)
            {
                foreach(string Clause in Clauses)
                {
                    if (FirstPass)
                    {
                        sb.Append(" WHERE ");

                        FirstPass = false;

                    }
                    else
                    {
                        sb.Append(" AND ");

                    }

                    sb.Append(Clause);

                }

            }

            MethodResult = sb.ToString();

        }
        catch //(Exception ex)
        {
            //ex.HandleException()
        }
        return MethodResult;
    }

0

앞서 언급했듯이 연결을 통해 SQL을 생성하는 것은 결코 좋은 생각이 아닙니다 . SQL 주입 때문 만은 아닙니다. 대부분은 추악하고 유지 관리가 어렵고 완전히 불필요하기 때문 입니다. 프로그램이 생성하는 SQL을 확인하려면 추적 또는 디버그를 사용하여 프로그램을 실행해야합니다. 당신이 사용하는 경우 QueryFirst (면책 조항 : 내가 쓴) 불행한 유혹이 제거되고, 당신은 SQL에서 지내 따 똑바로 얻을 수 있습니다.

이 페이지 에는 검색 조건자를 동적으로 추가하기위한 TSQL 옵션에 대한 포괄적 인 내용이 있습니다. 다음 옵션은 검색 술어 조합의 선택을 사용자에게 맡기려는 상황에 유용합니다.

select * from table1
where (col1 = @param1 or @param1 is null)
and (col2 = @param2 or @param2 is null)
and (col3 = @param3 or @param3 is null)
OPTION (RECOMPILE)

QueryFirst는 C # null to db NULL을 제공하므로 적절한 경우 null을 사용하여 Execute () 메서드를 호출하면 모두 작동합니다. <오피니언> C # 개발자가 더 간단하더라도 SQL로 작업하기를 꺼리는 이유는 무엇입니까? 마음이 흔들립니다. </ opinion>


0

더 긴 필터링 단계의 경우 StringBuilder가 많은 사람들이 말하는 더 나은 접근 방식입니다.

귀하의 경우에는 다음과 같이 갈 것입니다.

StringBuilder sql = new StringBuilder();

if (condition1) 
    sql.Append("AND Col1=0 ");
if (condition2) 
    sql.Append("AND Col2=1 ");
if (condition3) 
    sql.Append("AND Col3=2 ");

string Query = "SELECT * FROM Table1 ";
if(sql.Length > 0)
 Query += string.Concat("WHERE ", sql.ToString().Substring(4)); //avoid first 4 chars, which is the 1st "AND "

0

아래 이미지와 같이 간결하고 우아하며 달콤합니다.

여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.