क्या इसकी शुरुआत में 1 = 1 का उपयोग करके SQL SQL क्लॉज को गतिशील रूप से बनाने का एक बेहतर तरीका है?


110

मैं C # में कुछ SQL क्वेरी बना रहा हूँ । यह कोड में चर के रूप में संग्रहीत कुछ शर्तों के आधार पर भिन्न होगा।

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 का परीक्षण सुरुचिपूर्ण नहीं लगता है। यदि मैंने इसका उपयोग नहीं किया, तो मुझे हर बार यह याद रखना और जांचना होगा कि क्या "जहाँ" पहले से ही क्वेरी में जोड़ा गया था या नहीं।

क्या कोई अच्छा समाधान है?


118
ईमानदार होने के लिए - मैं इसे इस तरह से भी करूंगा, लेकिन मैं इसका इस्तेमाल करता हूं 42 = 42;-)
फिरो

5
मैं वास्तव में हमेशा इस तरह से अपने प्रश्नों को लिखता हूं। एक शर्त पर टिप्पणी करना आसान बनाता है
Deruijter

4
@ कॉटफूड एक इंटर्न के रूप में मेरा पहला प्रोजेक्ट था, जो हमारे साइबेस सर्वर के खिलाफ प्रदर्शन क्वेरी का विश्लेषण करने में मदद करने के लिए उपकरण लिख रहा था। एक मनोरंजक खोज सैकड़ों सैकड़ों Select 42प्रश्न थे जो हम प्राप्त कर रहे थे। (मनोरंजक स्रोत को ट्रैक करने की कोशिश नहीं कर रहा था)
श्री। मिन्दोर

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। डेटाबेस इंजन वैसे भी इसका अनुकूलन करता है, इसलिए जब यह बदसूरत दिख सकता है, तो यह समस्या को हल करने का सबसे आसान तरीका है।
रॉबर्ट हार्वे

4
यद्यपि दिए गए उत्तर बहुत अच्छे हैं, मुझे लगता है कि आपका मूल कोड पढ़ने में सबसे आसान है।
उउउ

जवाबों:


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>
फेर

101
मैं यह प्रदान करता है सभी SQL इंजेक्शन अवसरों के लिए उत्साहित हूँ।
ऐस्टर

12
@Jeff यदि आप उन मानों को हार्ड-कोडिंग नहीं कर रहे हैं, जहाँ क्लॉज़ में आप केवल 2 लिस्ट में SqlParameters भी रख सकते हैं। आपको सिर्फ़ उसी समय उस सूची को पॉप्युलेट करने की ज़रूरत है, जैसे ही स्थिति सूची और अंत में AddRange (पैरामीटर.ToArray ()) को कॉल करें ।
स्कॉट चैंबरलेन

5
@ScottChamberlain हाँ, आप सूची में डालने से पहले केवल इनपुट स्ट्रिंग्स से बच सकते हैं। मैं ज्यादातर सिर्फ मुखर हास्य का उपयोग करके एक संभावित हमले के खिलाफ चेतावनी दे रहा था।
ऐस्टर

4
यदि स्थिति उपयोगकर्ता इनपुट (मूल उदाहरण शामिल नहीं है) में @Jeff यह केवल SQL इंजेक्शन के लिए असुरक्षित है
D स्टेनली

85

इसका एक उपाय यह है कि स्ट्रिंग्स को जोड़कर केवल प्रश्नों को मैन्युअल रूप से न लिखा जाए। आप एक ORM का उपयोग कर सकते हैं, जैसे Entity Framework , और LINQ से 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 के लिए डैपर के प्रदर्शन की तुलना करने के लिए खोज कर रहा था, और मैं यहां Google द्वारा प्राप्त करता हूं, इसलिए मैंने सोचा था कि उत्पन्न PrintResults(query)क्वेरी फिर डैपर में क्वेरी के रूप में उपयोग करेगी !!
वाहीड्स

@ कवच ठीक है, लेकिन एक उत्तर को समझना समझ में नहीं आता है। अगर वह आप थे, जो संयोग से आपकी टिप्पणी के रूप में उसी समय हुआ था।
कोडकस्टर

आपका अधिकार, यह गलतफहमी थी। मैं जटिल प्रश्नों पर खराब प्रदर्शन के लिए लाइनक से पीड़ित हूं। मैंने आपके वोट के अन्य वोटों के द्वारा डाउन वोट की भरपाई की;)
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);

इस तरह अगर कोई स्थितियां नहीं मिलती हैं, तो आप क्वेरी में एक स्टेटमेंट लोड करने में भी परेशान नहीं होते हैं और एसक्यूएल सर्वर को जंक प्रसंस्करण का एक सूक्ष्म-सेकंड बचाते हैं जहां यह एसक्यूएल स्टेटमेंट को पार्स करता है।


मैं यह नहीं देखता कि यह इसे और अधिक सुरुचिपूर्ण कैसे बनाता है। यह निश्चित रूप से अधिक स्पष्ट नहीं है कि यहां क्या हो रहा है। मैं उस उपयोगिता फ़ंक्शन का उपयोग देख सकता हूं, लेकिन यह अधिक सुरुचिपूर्ण नहीं है।
यूआर

आपने हमें एक माइक्रो-सेकंड के महत्व के बारे में
बताने के

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 विशेष रूप से उस से बचने के लिए मौजूद है।
गयूस

तो स्विच करने के लिए String query = "SELECT * FROM Table1";और string jointer = " WHERE ";?
ब्रेंडन लॉन्ग

तब @BrendanLong WHEREरहे ANDरों की स्थिति के बीच रखा जाना?
पेंग्विनकोडर

@PenguinCoder एक टिप्पणी में पूर्ण कोड दिखाना मुश्किल है। मेरा मतलब था कि string joinerलाइन को बदलें string joiner = " WHERE ";, और joiner = " AND ";लाइन को अकेला छोड़ दें ।
ब्रेंडन लॉन्ग

@Gaius मैंने माना कि कोडन गैर-रिक्त है, लेकिन WHERE को जॉइनर में डालकर ट्रिक करना चाहिए। टिप्पणी के लिए धन्यवाद!
डेरियस

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 इंजेक्शन सुरक्षित और IMHO है , यह बहुत साफ है। Remove()बस आख़िरी को हटा AND;

यह दोनों काम करता है अगर कोई स्थिति निर्धारित नहीं की गई है, अगर कोई सेट किया गया है या यदि कई सेट किए गए हैं।


1
मुझे यकीन नहीं है (सी # का उपयोग न करें), लेकिन मैं कहूंगा कि conditions != nullहमेशा से है true, जैसा कि आप इसे ""(जब तक सी # में नहीं है "" == 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 और "या" WHERE 1 = 1 "शामिल है। यह स्थिति हो सकती है यदि स्थिति में एक सबक्वेरी होती है या कुछ जाँचने का प्रयास करता है। उदाहरण के लिए कॉलम में यह पाठ है। हो सकता है कि यह आपके मामले में कोई समस्या न हो, लेकिन आपको इसे ध्यान में रखना चाहिए ... "

इस मुद्दे से छुटकारा पाने के लिए, हमें "मुख्य" WHERE 1 = 1 और उन सबक्विरी से अलग करने की आवश्यकता है , जो आसान है:

सीधे शब्दों में करना "मुख्य" जहां विशेष: मैं एक "$" पर हस्ताक्षर संलग्न करेंगे

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हैक का उपयोग करने से बेहतर या बुरा नहीं है । लेकिन यह एक विचारणीय योगदान है।
कैटफ़ूड

3
एक त्रुटि हुई। इसे ठीक किया। यदि कोई भी स्थिति मौजूद नहीं थी, तो मेरी क्वेरी पर बमबारी होगी: -पी फिर भी मुझे कहना होगा कि अहमद या कोडकैस्टर मेरे लिए सबसे अच्छा समाधान हैं। मैंने केवल आप लोगों के लिए एक विकल्प प्रस्तुत किया है!
अंशुमान

यह अभी भी गलत है, सामान्य तौर पर। मान लीजिए कि यह था ... FROM SOMETABLE WHERE ; तब TrimEndवास्तव में यह कम हो जाएगा ... FROM SOMETABL। यदि यह वास्तव में था StringBuilder(जो कि यह होना चाहिए यदि आपके पास इस बहुत अधिक स्ट्रिंग हेरफेर या अधिक है) तो आप बस कर सकते हैं Query.Length -= "WHERE ".Length;
मार्क हर्ड

निशान, यह काम करता है। मैंने कई परियोजनाओं में यह कोशिश की है। यह कोशिश करो और आप पाएंगे कि यह करता है!
अंशुमान

8
बदसूरत नरक के रूप में :) इसके अलावा अगर मैं सही ढंग से गिना जाए तो यह 7 तार तक बना सकता है
Piotr Perak

5

मौजूदा क्वेरी बिल्डर का उपयोग क्यों नहीं किया जा रहा है? सक् कत कुछ ऐसा

यह उन जटिल परिस्थितियों का समर्थन करता है जहाँ स्थितियाँ, जुड़ाव और उपश्रेणियाँ हैं।

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 का उपयोग करने के लिए कोडकैस्टर की सिफारिश का उल्लेख करूंगा। लेकिन अगर आप सोचते हैं कि यह यहाँ क्या कर रहा है, तो आप वास्तव में स्मृति के 4 वर्णों को बर्बाद करने के बारे में चिंतित नहीं हैं, और कंप्यूटर के लिए पॉइंटर 4 स्थानों को स्थानांतरित करना वास्तव में बहुत जल्दी है।

यदि आपके पास ORM का उपयोग करने का तरीका सीखने का समय है, तो यह वास्तव में आपके लिए भुगतान कर सकता है। लेकिन इस संबंध में, यदि आप SQL db को हिट करने से उस अतिरिक्त स्थिति को बनाए रखने की कोशिश कर रहे हैं, तो यह आपके लिए यह कर देगा।


4

यदि यह SQL सर्वर है , तो आप इस कोड को अधिक क्लीनर बना सकते हैं।

यह एक ज्ञात संख्या मानदंड भी मानता है, जो संभावनाओं के बारे में सोचने पर एक खराब धारणा हो सकती है।

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

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

मुझे स्ट्रिंगर का धाराप्रवाह इंटरफ़ेस पसंद है, इसलिए मैंने कुछ 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 (I 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 सर्वर इसे वैसे भी अनुकूलित करेगा।


SELECT * FROM Table1 WHERE AND Col1=0सही नहीं लगता है, जो पूरे बिंदु है WHERE 1=1
मोर्मगिल

2

Dapper SqlBuilder एक बहुत अच्छा विकल्प है। इसका उपयोग StackOverflow पर उत्पादन में भी किया जाता है।

इसके बारे में सैम का ब्लॉग प्रविष्टि पढ़ें ।

जहाँ तक मुझे पता है, यह किसी भी Nuget पैकेज का हिस्सा नहीं है, इसलिए आपको इसके कोड को अपने प्रोजेक्ट में कॉपी करने या Dapper स्रोत को डाउनलोड करने और SqlBuilder प्रोजेक्ट बनाने की आवश्यकता होगी। किसी भी तरह, आपको DynamicParametersकक्षा के लिए डैपर को भी संदर्भित करना होगा ।


1
मुझे नहीं लगता कि डैपर का SqlBuilder उस पैकेज में शामिल है।
रॉनी ओवरबी

1

मैं देख रहा हूँ कि यह हर समय ऑरेकल में संग्रहीत प्रक्रियाओं के भीतर गतिशील एसक्यूएल के निर्माण में उपयोग होता है । मैं डेटा प्रश्नों की खोज के साथ-साथ डेटा के विभिन्न फ़िल्टर के बीच तेज़ी से स्विच करने के लिए प्रश्नों में इसका उपयोग करता हूं ... बस एक शर्त बताएं या इसे आसानी से वापस जोड़ें।

मुझे लगता है कि आपके कोड की समीक्षा करने वाले किसी व्यक्ति को समझने के लिए यह काफी सामान्य और आसान है।


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);
    }

अनाज जा रहा है!
रॉनी ओवरबी ने

माफ कीजिये? डु का क्या मतलब है?
मैक्सिम झूकोव

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 बनाता है। अगर आप QueryFirst का उपयोग करते हैं (अस्वीकरण: जो मैंने लिखा है) का उपयोग करते हैं तो दुखी प्रलोभन को हटा दिया जाता है, और आप सीधे टा टाइन में इसे एसक्यूएल में प्राप्त कर सकते हैं।

इस पृष्ठ में गतिशील रूप से खोज विधेय को जोड़ने के लिए 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 आपको d # NULL को C # null देता है, इसलिए आप उपयुक्त होने पर नल के साथ Execute () विधि को कॉल करते हैं, और यह सब काम करता है। <राय> C # देवता SQL में सामान करने के लिए इतने अनिच्छुक क्यों हैं, भले ही यह सरल हो। दिमाग चकराता है। </ राय>


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

संक्षिप्त, सुरुचिपूर्ण और मधुर, जैसा कि नीचे दी गई छवि में दिखाया गया है।

यहां छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.