처음에 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.